web-dev-qa-db-ja.com

WiXセットアッププロジェクトからWiXライブラリプロジェクトで定義されたWixVariableを参照する

ライブラリ内のファイルの1つのバージョンがセットアップのProduct/@ Versionとして使用されるように、WiXセットアップとライブラリを構成しようとしています。

背景

ローカルで定義されたファイルを使用するセットアップでは、コンポーネントプロジェクトがWiXプロジェクトによって参照され、構成されていると想定するという点で、これは比較的簡単です。

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

次に、製品バージョンを次のように設定できます。

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

問題

そのため、すべてのコンポーネントをWiXライブラリプロジェクトに移動すると、!(bind.FileVersion.$(var.Company.AssemblyFile.TargetFileName))変数を直接参照することはできなくなります。

ライブラリでWixVariableを構成してみました

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

そして、セットアップからそれを参照します

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

成功せずに。

WixVariable(またはその派生)をセットアップからアクセスできるようにするために、ライブラリまたはセットアップのいずれかに必要な追加の手順または構文はありますか?

23

私はこれをよく耳にしますが、WiXのドキュメントが状況を説明するのに特に良い仕事をしているとは思わないので、ここにあります。簡単に言えば、構文は正しいということです。 WixVariable要素で宣言された変数は構文!(wix.VariableName)で参照され、参照されたライブラリで定義された変数を使用できるため、!(wix.BuildVersion)はこの例に適していますあなたは上で与えました。これが機能しない理由は、コンパイルフェーズで値を検証する必要があるが、リンクフェーズまで値が生成されないためです。だからここに長い答えがあります:

* .wxsファイルで参照できる変数には2つの異なるタイプがあります。 プリプロセッサ変数およびバインダー(またはリンカー)変数。前者は$構文で参照されます。例: $(var.VariableName)および後者は!で参照されます構文、例: !(bind.FileVersion.FileId)。主な違いは単純です。プリプロセッサ変数はコンパイルフェーズ(candle.exe)で解析され、バインダー変数はリンクフェーズ(light.exe)で解析されます。コンパイラは、ソース* .wxsファイルを取得して* .wixobjファイルにコンパイルする責任があります。実際のペイロードを処理しないため、リンクされたファイルからバージョン情報を読み取ることはできません。次に、*。wixobjファイルは、ペイロードを処理してMSIデータベースを作成するリンカーに渡されます。リンカはペイロードからメタデータを収集する役割を果たします。そのため、リンカは!(bind.FileVersion.FileId)などの変数に値を提供できます。

WixVariable要素で宣言された変数は!で参照されることに注意してください。構文なので、バインダー変数です。 light.exeでは使用できますが、candle.exeでは使用できません。 Candle.exeはProduct/@ Versionなどの特定のフィールドに検証を適用するため、これは問題です。 !(wix.BuildVersion)が何に評価されるかわからないため、有効なバージョンが生成されるかどうかを検証できません。対照的に、candleはコンパイル時に満足し、リンク時に有効なバージョンに解決されるため、!(bind.FileVersion.FileId)を回避できます(FileIdは製品内のファイルへの直接参照であるため、candleはそれを信頼しますリンク上のバージョン番号を生成するために存在します)。

したがって、*。wxsの他の場所で!(wix.BuildVersion)を使用できますが、Product/@Versionの値として使用することはできません。私の知る限り、ここで使用できるバインダー変数は!(bind.FileVersion.FileId)だけですが、参照されているライブラリから値を取得する場合は、これは明らかに適切ではありません。それ以外の場合は、バージョン情報を別の場所から取得してWiXに渡すだけで、コンパイル時に利用できるようになります。 MSBuildを使用している場合は、GetAssemblyIdentityタスクを使用してバージョン情報をクエリし、DefineConstantsプロパティを介してこれをWiXに渡すことができます。 * .wixprojファイル内の次のターゲットがそれを実行する必要があります。

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

BuildVersionプロパティはcandle.exeに渡されるため、プリプロセッサ変数$(var.BuildVersion)で参照できます。これは確かにすべてを* .wxsファイルに保持するほどクリーンではありませんが、バージョン情報をキャンドルに入れてProduct/@Versionの変数として使用できるようにする1つの方法です。私は確かにこれを行うためのより良い方法を聞きたいです。

49
Anon

Heat.exeを使用しているときに同様の問題が発生しました。これにより、システム環境変数などをいじることなく、ソース変数をオーバーライドできました。

"%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"

この構文は、リンク時に機能しない変数宣言に使用できると思います。

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

多分他の場所でも役に立ちます。