14

現在、Wix プロジェクトを MSBuild に統合しています。複数の値を Wix プロジェクトに渡す必要があります。1 つの値が機能します (以下のサンプルの ProductVersion)。

<Target Name="BuildWixSetups">
    <MSBuild Condition="'%(WixSetups.Identity)'!=''"
                Projects="%(WixSetups.Identity)"
                Targets="Rebuild" Properties="Configuration=Release;OutputPath=$(OutDir);DefineConstants=ProductVersion=%(WixSetups.ISVersion)" ContinueOnError="true"/>
</Target>

ただし、DefineConstants キーに複数の値を渡すにはどうすればよいでしょうか。すべての「論理」セパレーター (スペース、コンマ、セミコロン、パイプ記号) を試しましたが、うまくいきません。

他の誰かがこの問題に遭遇しましたか?

うまくいかない解決策:

  1. DefineConstants 要素を追加しようとしても機能しません。これは、DefineConstants を Properties 属性内で表現する必要があるためです。
4

12 に答える 12

14

問題:

MSBuildタスク(MSBuild.exeではなく、MSBuildという名前のMSBuildタスク)は、WIXプロジェクトで使用される複数の定数を処理できません。通常、ビルドスクリプトで次のようにプロパティを指定します。

<MSBuild Projects="YourSolution.sln" Properties="Configuration=MyConfig;Platform=x86;DefineConstants=&quot;SOMETHING=1;SOMETHINGELSE=2&quot;" />

ただし、ビルドログを見ると、MSBuildは定数を分離し、期待どおりに値をグループ化したままにしないことがわかります。次のようになります。

Task "MSBuild" Global Properties:
Configuration=MyConfig
Platform=x86
DefineConstants="SOMETHING=1
SOMETHINGELSE=2"

したがって、candleがこれらの定数を使用しようとすると、通常、「エラーCNDL0150:未定義のプリプロセッサ変数'$(var.SOMETHINGELSE)'」で応答します。これは、MSBuildタスクが値に複数の'='を含むプロパティを適切に処理していないことを意味します。引用符でグループ化されている場合プロパティ値が引用符でグループ化されていない場合、それらは単一の値ではなく、明らかに個別のプロパティとして扱われる必要があります。

回避策:

この問題を修正するには、MSBuild.exeを直接呼び出して、それらの値を手動で渡す必要があります。

msbuild.exe /p:Configuration=MyConfig /p:Platform=x86 /p:DefineConstants="SOMETHING=1;SOMETHINGELSE=2" YourSolution.sln

これにより、WiXインストールプロジェクトを再設計することなく、定数を希望どおりに動作させることができます。

注:単一の定数のみを使用している場合でも、次のようにMSBuildタスクを使用できます。

<MSBuild Projects="YourSolution.sln" Properties="Configuration=MyConfig;Platform=x86;DefineConstants=&quot;SOMETHING=1&quot;" />
于 2010-04-26T21:24:47.367 に答える
14

問題は、名前と値のペアを MSBuild タスクに渡し、MSBuild でそれらを適切に解析して、Candle タスクに渡すことができるようにすることにあります。MSBuild は単純な名前のリスト、または単一の名前と値のペアを処理できますが、ペアのリストは処理できないようです。

私の解決策は、リストが MSBuild タスクに渡されたときにエスケープし、Candle タスクに渡されたときに再びエスケープ解除することです。

MSBuild ファイルで、次のようにプロパティでペアを定義します。

<PropertyGroup>
    <WixValues>
        One=1;
        Two=2;
        Three=3;
    </WixValues>
</PropertyGroup>

MSBuild タスクを呼び出すときに、プロパティをエスケープします (MSBuild 4 が必要です)。

<MSBuild 
    Projects="setup.wixproj"
    Properties="WixValues=$([MSBuild]::Escape($(WixValues)))" />

アンエスケープは wixproj ファイルで行う必要がありますが、手動でファイルを編集する必要はありません。プロジェクトのプロパティを開き、[ビルド] タブに移動して、「プリプロセッサ変数を定義する」と表示されている場所に次のように入力します。

$([MSBuild]::Unescape($(WixValues)))

これは、そのボックスに他の変数が既にある場合でも機能します。これをセミコロンとともにリストに追加するだけです。

candle.exeツールが引数を正しく受け取っていることが MSBuild ログに表示されます。

candle.exe -dOne=1 -dTwo=2 -dThree=3 -dConfiguration=Release...
于 2010-11-25T19:53:33.973 に答える
4

これを機能させるにはまだ多くの問題がありましたが、上記の各回答の一部が私の解決策に貢献したので、共有したいと思いました.

環境: TFS Build Server 2010 - MSBuild.exe Wix 3.6 を呼び出す Powershell がビルド サーバーにインストールされている

目標は、ビルド バージョン番号と 5 つのディレクトリを MSBuild に渡して、Candle.exe が正しく受け取るようにすることです。

ビルドはビルドの最後にコマンド ファイルを呼び出します。そのコマンド ファイルには、PowerShell スクリプトを呼び出して Wix インストーラーをビルドするステップが含まれています。ビルドのバージョン番号、ソース ディレクトリ、および出力ディレクトリを渡します (出力は UNC ファイル共有参照 \tfsbuildserver.. です)。

動作させるには、Powershell ps1 ファイルで、

  • double で始まる単一の /p:DefineConstants= を使用する "
  • すべての区切りをエンコードします。%3bとして
  • = はエンコードされていなくても問題ありません
  • スペースを含むファイル名を引用符で囲んではいけません

    $msbuild = "C:\Windows\Microsoft.NET\Framework64\v4.0.30319\MSBuild.exe"
    
    $options = " /p:Configuration=Release /p:Platform=x64 "
    $options = $options + " /p:DefineConstants="""
    $options = $options + "SolutionDir=" + $SourceDir
    $options = $options + "%3bTFSBuildSourceLanding=" + $OutputLocation + "SharepointWebRoot\Landing"
    $options = $options + "%3bTFSBuildSourceLandingAdmin=" + $OutputLocation + "SharepointWebRoot\LandingAdmin"
    $options = $options + "%3bTFSBuildSourceRegistration=" + $OutputLocation + "Extranet_Registration"
    $options = $options + "%3bTFSBuildSourceGAC=" + $OutputLocation + "GAC"
    $options = $options + "%3bTFSBuildSourceSQL=" + $OutputLocation + "SQL"
    $options = $options + "%3bProductVersion=" + $BuildVersion + """" 
    
    
    $build = $msbuild + " ""EUM WIX\EUM Wix.wixproj"" " + $options + " /t:Build"
    $clean = $msbuild + " ""EUM WIX\EUM Wix.wixproj"" " + $options + " /t:Clean"
    
    
    Write-Host "Building Wix Installer..."
    Invoke-Expression $clean
    Invoke-Expression $build
    
  • wixproj ファイル内で、エスケープを解除する必要があります (下部で、変更するにはコメントを解除するように指示されています)。

      <Target Name="BeforeBuild">
          <CreateProperty Value="$([MSBuild]::Unescape($(DefineConstants)))">
             <Output TaskParameter="Value" PropertyName="DefineConstants" />
          </CreateProperty>
      </Target>
    
  • また、Visual Studio ではデバッグ設定を使用し、[ビルド] タブの [プリプロセッサ変数の定義] でこれらの値のデフォルトを設定できることにも注意してください。

  • リリース設定では、この項目は上記のコマンド ラインで渡されるため、空白にする必要があります。

于 2012-08-30T15:13:39.737 に答える
2

定数ではなく、パラメーターとして渡すことができます。コードは次のようになります。

<MSBuild ...
    Properties="ProductVersion=%(WixSetups.ISVersion)" />

今WiXプロジェクトで定数を追加します:

<DefineConstants>BuildVersion=$(ProductVersion)</DefineConstants>

そして、必要に応じて*.wxsファイルで使用します。

$(var.BuildVersion)

例えば:

<Product Id="*" Name="My Company" Language="1033" Version="$(var.BuildVersion)"... />

これは複数のパラメーターで機能します。

于 2012-03-13T15:49:28.673 に答える
2

MSBuild タスクを使用して Visual Studio ソリューションをビルドする場合、次のように動作します。

<MSBuild Projects="Solution.sln"
         Targets="Rebuild"
         Properties="Configuration=Debug;DefineConstants=DEBUG%3bTRACE" />

トリックは、値内のセパレーター%3bをエスケープするために使用しています。これがあまりにもうまくいくかどうかはわかりません。としてエスケープする必要があるか、まったく機能しない可能性があります...;DefineConstants=%3d

TargetAndPropertyListSeparatorsMSBuild 要素にも属性があります。ドキュメントは見つかりませんが、それを使用して 以外のセパレータを設定できる可能性があります;

于 2010-09-13T06:46:36.603 に答える
1

MSDN のドキュメントにはエラーがたくさんあり、誤解を招くこともあります。

条件付きコンパイラ定数を定義します。シンボルと値のペアはセミコロンで区切られ、次の構文を使用して指定されます。

シンボル1 = 値1; シンボル 2 = 値 2

このプロパティは、/define コンパイラ スイッチと同等です。

http://msdn.microsoft.com/en-us/library/bb629394.aspx

MSDN によると、1. 複数の定数を定義し、2. (@Sayed) 値を割り当てることができます。

ただし、MSBuild タスクのこのプロパティの期待どおりの動作を得ることができず、Jeff Winn の回避策をお勧めします。彼の投稿は回答としてマークする必要があります。

于 2010-05-06T15:14:44.380 に答える
1

次の行は、(Visual Studio 2010 を使用して) .wixproj ファイルに含めたときに機能しました。

<PropertyGroup>
  <DefineConstants>Const1=Value1;Const2=Value2;Const3=Value3</DefineConstants>
</PropertyGroup>
于 2010-11-09T22:45:53.390 に答える
0

回避策のハック。

仮定:

  • SomeEnumValue の可能な値は EnumValue1 と EnumValue2 です

MSBuild では:

<DefineConstants>Debug;use_$(SomeEnumValue)</DefineConstants>

WiX の場合:

<?ifdef $(var.use_EnumValue1) ?>
  ...
<?elseif $(var.use_EnumValue2) ?>
  ...
<?endif?>
于 2010-07-30T00:47:35.720 に答える
0

このようなものが機能するはずだと思います。

<DefineConstants>DEBUG;TRACE</DefineConstants> 

このブログ投稿をチェックして、役立つかどうかを確認してください。 http://www.sedodream.com/PermaLink,guid,9b1d23aa-6cb2-48cb-a47a-9cef29622676.aspx

このフォーラムの投稿も確認してください。それはあなたと同様の問題を解決します。 http://social.msdn.microsoft.com/Forums/en-US/msbuild/thread/3f485bf4-1b00-48bf-b5d0-4b83341ce4a6/

于 2009-02-03T11:00:34.037 に答える
-1

これは私にとってはうまくいき、まだ定義されていないキーと値のペアを持つアイテムを渡すことができました。最もエレガントではありませんが、私はコーダーではありません。

msbuild test.proj /p:PassedInProp="ProductVersion=45;rt=669;wewanttoknow=test5"

<?xml version="1.0" encoding="utf-8" ?>
<Project ToolsVersion="4.0" DefaultTargets="Test" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup>
    <test Include="$([MSBuild]::Unescape($(PassedInProp)))" />
  </ItemGroup>
 <Target Name ="Test">
    <CreateItem Include ="$([System.String]::New('%(test.identity)').Split('=')[0])" AdditionalMetadata="value=$([System.String]::New('%(test.identity)').Split('=')[1])">
      <Output TaskParameter="Include" ItemName ="Test2"/>
    </CreateItem>
    <Message Text ="Key: %(test2.identity)  Value: %(test2.value)"/>
  </Target>
</Project>
于 2012-06-22T02:21:33.827 に答える
-2

なぜ DefineContstants=ProductVersion=XXXXXX を指定するのですか?

DefineConstants の場合、値を割り当てていません。定数 (DEBUG や TRACE など) が定義されているか、定義されていません。このプロパティは、/define C# コンパイラ スイッチに関連しています。あなたは本当に何をしようとしていますか?

また、私のブログ投稿が「ハック」であるとあなたが言うとき、それが2回構築されたという事実が要点です。

于 2009-07-01T19:44:52.580 に答える