¿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

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.


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/


¿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>

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>

@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.


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

Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.