wix wix3.5

Referencia a una WixVariable definida en un proyecto de biblioteca WiX desde un proyecto de configuraciĆ³n de WiX



wix3.5 (2)

Estoy intentando configurar una configuración de WiX y una biblioteca para que la versión de uno de los archivos de la biblioteca se utilice como la versión Producto / @ en la configuración.

Fondo

En una configuración con los archivos definidos localmente, esto es relativamente sencillo ya que se supone que el proyecto WiX hace referencia al proyecto del componente y luego se configura:

<Component Id="Company.Assembly" Guid="[GUID]"> <File Id="Company.AssemblyFile" Name="Company.Assembly.dll" KeyPath="yes" DiskId="1" Source="$(var.Company.Assembly.TargetPath)" /> </Component>

Entonces la versión del producto se puede configurar como

<Product Id="[GUID]" Name="Product Name" Language="1033" Version="!(bind.FileVersion.$(var.Company.AssemblyFile .TargetFileName))" Manufacturer="Company Name" UpgradeCode="[GUID]">

Problema

Por lo tanto, después de mover todos los componentes a un proyecto de la Biblioteca WiX, ya no es posible hacer referencia directamente a la !(bind.FileVersion.$(var.Company.AssemblyFile.TargetFileName)) .

He intentado configurar una WixVariable en la biblioteca

WixVariable Id="BuildVersion" Value="!(bind.FileVersion.Company.AssemblyFile)"/>

Y luego referencia eso desde la configuración

<Product Id="[GUID]" Name="Product Name" Language="1033" Version="!(wix.BuildVersion)" Manufacturer="Company Name" UpgradeCode="[GUID]">

Sin éxito.

¿Se requiere algún paso o sintaxis adicional en la biblioteca o en la configuración para hacer que la WixVariable (o alguna derivación de ella) sea accesible desde la configuración?


Escuché esto mucho y no creo que la documentación de WiX explique la situación particularmente bien, así que aquí está. La respuesta corta es que su sintaxis es correcta; se hace referencia a una variable declarada con el elemento WixVariable con la sintaxis !(wix.VariableName) y puede usar variables que se han definido en una biblioteca referenciada, por lo que !(wix.BuildVersion) es correcta para el ejemplo que se ha dado anteriormente. La razón por la que no funciona es porque el valor debe verificarse durante la fase de compilación, pero no se genera hasta la fase de vinculación. Así que aquí está la respuesta larga:

Hay dos tipos distintos de variables a las que puede hacer referencia en un archivo * .wxs; Variables de preprocesador y variables de enlace (o vinculador ). Se hace referencia a la primera con la sintaxis $, por ejemplo, $(var.VariableName) y la última se hace referencia con la! sintaxis, por ejemplo !(bind.FileVersion.FileId) . La diferencia clave es simple: las variables del preprocesador se analizan durante la fase de compilación (por candle.exe) y las variables de enlace se analizan durante la fase de enlace (por light.exe). El compilador es responsable de tomar los archivos fuente * .wxs y compilarlos en archivos * .wixobj; no procesa la carga útil real, por lo que no está en posición de leer la información de versión de un archivo vinculado. Los archivos * .wixobj se pasan luego al vinculador, que procesa la carga útil y crea la base de datos MSI. El enlazador es responsable de recopilar metadatos de la carga útil, por lo que puede proporcionar valores para variables como !(bind.FileVersion.FileId) .

Tenga en cuenta que una variable declarada con el elemento WixVariable está referenciada con el! sintaxis por lo que es una variable de enlace; estará disponible para light.exe pero no estará disponible para candle.exe. Este es un problema porque candle.exe aplica la validación a ciertos campos como Product / @ Version. ¡No tiene idea de qué !(wix.BuildVersion) , por lo que no puede verificar que produzca una versión válida. Por el contrario, puede salirse con !(bind.FileVersion.FileId) porque vela se satisface en el momento de la compilación y se convertirá en una versión válida en el momento del enlace (FileId es una referencia directa a un archivo en el producto, por lo que la vela confía en existirá para dar un número de versión en el enlace).

Por lo tanto, puede usar !(wix.BuildVersion) cualquier otro lugar de su * .wxs, pero no puede usarlo como un valor para Product / @ Version. Por lo que sé, la única variable de !(bind.FileVersion.FileId) que puede usar aquí es !(bind.FileVersion.FileId) pero obviamente esto no es bueno si desea obtener el valor de una biblioteca referenciada. De lo contrario, solo tendrá que obtener la información de su versión de otro lugar y pasarla a WiX para que esté disponible en tiempo de compilación. Si está utilizando MSBuild, puede consultar la información de la versión con la tarea GetAssemblyIdentity y puede pasarla a WiX a través de la propiedad DefineConstants. Los siguientes objetivos en su archivo * .wixproj deben hacerlo:

<Target Name="BeforeBuild"> <GetAssemblyIdentity AssemblyFiles="[Path.To.Target.File]"> <Output TaskParameter="Assemblies" ItemName="AsmInfo" /> </GetAssemblyIdentity> <CreateProperty Value="%(AsmInfo.Version)"> <Output TaskParameter="Value" PropertyName="BuildVersion" /> </CreateProperty> <CreateProperty Value="$(DefineConstants)"> <Output TaskParameter="Value" PropertyName="DefineConstantsOriginal" /> </CreateProperty> <CreateProperty Value="$(DefineConstants);BuildVersion=$(BuildVersion)"> <Output TaskParameter="Value" PropertyName="DefineConstants" /> </CreateProperty> </Target> <Target Name="AfterBuild"> <CreateProperty Value="$(DefineConstantsOriginal)"> <Output TaskParameter="Value" PropertyName="DefineConstants" /> </CreateProperty> </Target>

La propiedad BuildVersion se pasará a candle.exe para que pueda consultarla con la variable de preprocesador $ (var.BuildVersion). Ciertamente, esto no es tan limpio como mantenerlo todo en el archivo * .wxs, pero es una forma de obtener la información de la versión en vela para que se pueda utilizar como una variable en Product / @ Version. Ciertamente me gustaría escuchar alguna forma mejor de hacer esto.


Tuve un problema similar al usar Heat.exe, esto me permitió anular la variable de origen sin alterar las variables de entorno del sistema u otras similares:

"%wix%bin/heat.exe" dir "$(SolutionDir)Web/obj/$(Configuration)/Package" -cg PACKAGEFILES -gg -g1 -sreg -srd -dr DEPLOYFOLDER -var wix.PackageSource="$(SolutionDir)Web/obj/$(Configuration)/Package" -out "$(SolutionDir)WebInstaller/PackageFragment.wxs"

Creo que esta sintaxis se puede usar para cualquier declaración de variable que de otra manera no funcionará en el momento de la vinculación:

<wix.YOURVAR="VALUE">-in command line/<!(wix.YOURVAR="VALUE")>-in .WXS files

Tal vez útil en otros lugares también.