¿Cómo puedo configurar la versión del instalador de WiX a la versión de compilación actual?

134

Escribí una aplicación y su instalador WiX y la puse bajo control de versión usando subversion. Cuando el instalador de WiX compila, quiero que su número de versión sea la versión de compilación actual de la aplicación. ¿Cómo logro esto? Usé C # para codificar la aplicación.

Nota: estoy usando ccnet para construir este proyecto

Draco
fuente

Respuestas:

181

Puede usar Product/@Version="!(bind.FileVersion.FileId)"(reemplazar FileIdcon el Iddel archivo del que desea obtener el número de versión) y light.exe completará el valor con la versión del archivo al que hace referencia FileId.

Rob Mensching
fuente
44
¡Justo lo que estaba buscando! Aunque tuve que usar "! (Bind.FileVersion.FileId)" (a "!" En lugar de "$"), de lo contrario recibí un error de directiva del preprocesador.
Nicholas Piasecki
8
Sí, lo siento, constante error mental que hago. $ es variable de preprocesador y! es la variable aglutinante.
Rob Mensching
20
Tenga en cuenta que "Fileid" debe ser el valor de un elemento <File Id = "Fileid" ...>, y aparentemente puede incluir el carácter de punto (.).
James Hugard
66
¿Es posible hacer esto para un paquete / bootstrapper también?
noelicus
66
Un enlace a la documentación relacionada, sección: Variables de la carpeta
mcdon
39

Hice esto en uno de mis proyectos escribiendo una extensión de preprocesador para leer la versión del archivo de mi ejecutable. Entonces el archivo WiX se parece a:

<?define ProductName="$(fileVersion.ProductName($(var.MyApp.TargetPath)))" ?>
<?define CompanyName="$(fileVersion.CompanyName($(var.MyApp.TargetPath)))" ?>
<?define ProductVersion="$(fileVersion.ProductVersion($(var.MyApp.TargetPath)))" ?>
<Product 
    Id="<product ID>" 
    Name="$(var.ProductName)" 
    Version="$(var.ProductVersion)" 
    Manufacturer="$(var.CompanyName)" 
    Language="1033" 
    UpgradeCode="<upgrade code>">

Publiqué el código en CodePlex: http://wixfileversionext.codeplex.com/

Chris Kaczor
fuente
¿Su extensión todavía funciona? Intenté agregarlo como referencia y recibí un error.
Stefan Vasiljevic
Esta extensión funcionó muy bien con Wix 3.5, después de actualizar a Wix 3.9 arroja una NullPointerException. Obviamente, algo se rompió entre estas versiones.
Gigo
2
@Gigo Lo hice funcionar a través de <?define ProductName="!(bind.property.ProductName)" ?><?define CompanyName="!(bind.property.Manufacturer)" ?><?define ProductVersion=!(bind.FileVersion.FileId) ?> ¿Dónde FileIdestá el valor del Idatributo de uno de sus Fileelementos dentro de a Component.
Jared
El enlace CodePlex no se abre para mí. ¿Hay alguna otra forma, excepto escribir su propia extensión de preprocesador?
RDV
28

En caso de que alguien esté buscando un ejemplo XML real, esto funciona con ensamblados .NET (y no tiene que hacer los atributos Ensamblaje o KeyPath). Eliminé el código no relacionado con [...] marcadores de posición:

<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi">
    <Product [...] Version="!(bind.fileVersion.MyDLL)">
        [...]
        <Directory Id="TARGETDIR" Name="SourceDir">
            <Directory Id="ProgramFilesFolder" Name="PFiles">
                <Directory Id="INSTALLDIR" Name="MyDLLInstallLocation">
                    <Component Id="MainLib" Guid="[...]">
                        <File Id="MyDLL" Name="MyDll.dll" Source="MyDll.dll" />
                        [...]
                    </Component>
                    [...]
                </Directory>
            </Directory>
        </Directory>
    </Product>
</Wix>
K0D4
fuente
1
Esta es una respuesta mucho mejor. Gracias por el ejemplo de trabajo.
rueda el
¿Dónde está obteniendo el número de versión real?
foobar
@foobar Ha pasado un tiempo desde que estuve aquí, pero si miras la cadena !(bind.fileVersion.MyDLL), usa la tercera parte en referencia a la <File Id="MyDLL"...sección
K0D4
Esto funcionó bien para mí. Obras para ejecutables compilados, así como DLL que es ideal para fijar la versión del instalador y el contenido de la interfaz de usuario a la información de montaje exe, sin tener que cambiar las cosas en varios lugares
rcbevans
21

Aquí hay una manera muy simple de hacer que su versión del paquete Bootstrapper coincida con su versión de ensamblaje MyApp usando un BeforeBuild Targety DefineConstants.

Bundle.wxs:

<Bundle Name="$(var.ProductName) Bootstrapper v$(var.BuildVersion)"
     Version="$(var.BuildVersion)"

Bootstrapper.wixproj:

<Target Name="BeforeBuild">
  <GetAssemblyIdentity AssemblyFiles="..\MyApp\bin\$(Configuration)\MyApp.exe">
    <Output TaskParameter="Assemblies" ItemName="AssemblyVersion" />
  </GetAssemblyIdentity>
  <PropertyGroup>
    <DefineConstants>BuildVersion=%(AssemblyVersion.Version)</DefineConstants>
  </PropertyGroup>
</Target>
Brock Hensley
fuente
@AliKazmi ¿Has definido tu var.ProductNamey var.BuildVersionalgún lugar por encima de tu <Bundle>?
Brock Hensley
2
Intenté esto y no puedo recomendarlo lo suficiente: combínelo con el parche de ensamblaje para TeamCity y obtendrá una fórmula ganadora. No utilicé el elemento Bundle sino un elemento de producto y aún así funcionó para mí.
IbrarMumtaz
VS simplemente ama ignorar el BeforeBuildobjetivo, por lo que podría ser necesario especificar explícitamente AfterTargets="AfterResolveReferences"si está construyendo en el IDE
Dmitry
Agregué el código Bootstrapper.wixproj en mi * .wixproj y en el archivo Product.wxs, definí la variable buildversion como:
RDV
4

Puede pasar la versión al script de MSBuild para su proyecto de instalación de la misma manera que puede pasar el script de compilación de la aplicación.

Por ejemplo, si su sistema CI define variables AppVersiony las BuildNumberpasa a sus scripts MSBuild, su wixproj puede crear una Versionpropiedad correspondiente que reenvía a Wix de esta manera:

<PropertyGroup>
    <Version Condition=" '$(BuildNumber)' == '' ">0.0.1</Version>
    <Version Condition=" '$(BuildNumber)' != '' ">$(AppVersion).$(BuildNumber)</Version>
    <DefineConstants>Version=$(Version)</DefineConstants>
</PropertyGroup>

La primera definición de Versionproporciona un valor predeterminado para cuando está construyendo localmente. Cualquier cosa que termine se convierte en una Versionvariable en Wix. Úselo en un archivo wsx como este:

<Product Version="$(var.Version)" ...>
    <Package Description="$(var.ProductName) $(var.Version): $(var.ProductDescription)" ... />

Me gusta incluir la versión en la descripción para que sea fácil buscar desde el Explorador de Windows (como una columna en la Vista de detalles o en la página de Propiedades) independientemente del nombre del archivo.

Pasar la versión como una variable le da más control que leerlo desde un archivo. Cuando lee de un archivo, obtiene las 4 partes de la versión programática. Sin embargo, ProductVersion solo está diseñado para usar las primeras 3 partes.

Edward Brey
fuente
Gracias, esto me salvó el día. Por cierto: el código superior recortado va en su proyecto (* .wxiproj). Tener que administrar un Devops / VSTS CI-Build es la mejor respuesta. Como ya tengo lista mi variable de versión final. En mi caso, resultó: <Version Condition=" '$(BuildVersionOfAsm)' != '' ">$(BuildVersionOfAsm)</Version>mientras que BuildVersionOfAsm es una variable en las canalizaciones de DevOps.
Robetto
Quiero elegir Versión dinámicamente, este método requerirá que siga actualizando la versión en * .wixproj. ¿Hay alguna forma de versión de dll en este campo?
RDV
@RDV La intención con este enfoque no es cambiar ningún archivo en el control de origen, incluido el .wixproj. El sistema de CI proporciona el número de versión dinámica (AppVersion y BuildNumber en este ejemplo). Por lo general, establece los números de versión mayor y menor como variables de CI y deja que el sistema de CI genere el número de compilación dinámicamente.
Edward Brey
Excelente: el tipo de solución que necesitaba, incluido un valor predeterminado para las compilaciones locales.
ColH