2011-12-06 9 views
20

Estoy tratando de configurar una biblioteca y configuración de WiX para que la versión de uno de los archivos de la biblioteca se use como la versión de producto/@ en preparar.Hacer referencia a una WixVariable definida en un proyecto de biblioteca WiX desde un proyecto de configuración de WiX

Antecedentes

En una instalación con los archivos definidos localmente esto es relativamente sencillo en el que, suponiendo el proyecto componente hace referencia el proyecto de WiX y luego configurar:

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

A continuación, la versión del producto se puede establecer como

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

Edición

Así que se ha movido todos los componentes de un proyecto de biblioteca de WiX que ya no es posible hacer referencia directamente a la variable !(bind.FileVersion.$(var.Company.AssemblyFile.TargetFileName)).

He intentado configurar un WixVariable en la biblioteca

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

y luego hacer referencia que a partir de la configuración

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

sin éxito.

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

Respuesta

47

Escucho mucho esta y no creo que la documentación de WiX haga un trabajo particularmente bueno al explicar la situación, así que aquí está. La respuesta corta es que tu sintaxis es correcta; una variable declarada con el elemento WixVariable se referencia con la sintaxis !(wix.VariableName) y puede usar las variables que se han definido en una biblioteca a la que se hace referencia para que !(wix.BuildVersion) sea correcto para el ejemplo que proporcionó 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 enlace. Así que aquí está la respuesta larga:

Hay dos tipos distintos de variables que puede consultar en un archivo * .wxs; preprocesador variables y aglutinante (o enlazador) variables. El primero se referencia con la sintaxis $, p. $(var.VariableName) y el último se hace referencia con el! sintaxis, p. !(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 del enlazador 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 real, por lo que no está en condiciones de leer la información de la versión de un archivo vinculado. Los archivos * .wixobj se pasan luego al enlazador que procesa la carga útil y crea la base de datos MSI. El vinculador es responsable de recopilar los metadatos de la carga, por lo que puede proporcionar valores para variables como !(bind.FileVersion.FileId).

Tenga en cuenta que se hace referencia a una variable declarada con el elemento WixVariable con! sintaxis así que es una variable de encuadernación; estará disponible para light.exe pero no estará disponible para candle.exe. Esto es un problema porque candle.exe aplica la validación a ciertos campos como Product/@ Version.No tiene idea de qué evaluará !(wix.BuildVersion) para que no pueda verificar que arroje una versión válida. En contraste, puede salirse con la suya con !(bind.FileVersion.FileId) porque candle se satisface en tiempo de compilación que se resolverá en una versión válida en tiempo de enlace (FileId es una referencia directa a un archivo en el producto así que candle confía que existirá para producir una versión número en el enlace).

Para que pueda usar !(wix.BuildVersion) en cualquier otro lugar en su * .wxs pero no puede usarlo como valor para Product/@ Version. Por lo que yo sé, la única variable de encuadernación que puede usar aquí es !(bind.FileVersion.FileId), pero obviamente esto no es bueno si quiere obtener el valor de una biblioteca a la que se hace referencia. De lo contrario, solo tendrá que obtener la información de su versión en otro lugar y pasarla a WiX para que esté disponible en tiempo de compilación. Si está utilizando MSBuild, puede consultar información de la versión con la tarea GetAssemblyIdentity y puede pasar esto 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 lo que puede hacer referencia a ella con la variable $ preprocesador (var.BuildVersion). Esto ciertamente 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 pueda usarse como una variable en Product/@ Version. Ciertamente me gustaría escuchar mejores formas de hacerlo.

+1

Gracias, respuesta muy completa. Curiosamente, también has respondido a mi pregunta de seguimiento sobre cómo escribir una variable en DefineConstants. –

1

tuve un problema similar cuando se utiliza Heat.exe, esto me ha permitido para anular la variable de origen sin jugar con las variables de entorno del sistema o de otro tipo:

"%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 utilizar para cualquier declaración de variable que de otra manera no funcionaría en el tiempo de vinculación:

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

Quizás también sea útil en otros lugares.

Cuestiones relacionadas