使用MSBuild将多个值传递给Wix DefineConstants属性

Sar*_*kar 14 msbuild wix msbuild-task

我目前正在将我的Wix项目集成到MSBuild中.我有必要将多个值传递给Wix项目.一个值将起作用(下面示例中的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>
Run Code Online (Sandbox Code Playgroud)

但是,如何将多个值传递给DefineConstants键?我已经尝试了所有'逻辑'分隔符(空格,逗号,分号,管道符号),但这不起作用.

有其他人遇到过这个问题吗?

解决方案不起作用:

  1. 尝试添加DefineConstants元素不起作用,因为需要在Properties属性中表达DefineConstants.

Jef*_*inn 13

问题:

MSBuild任务(不是MSBuild.exe,名为MSBuild的MSBuild任务)无法处理WIX项目使用的多个常量.通常,您可以在构建脚本中指定属性,如:

<MSBuild Projects="YourSolution.sln" Properties="Configuration=MyConfig;Platform=x86;DefineConstants=&quot;SOMETHING=1;SOMETHINGELSE=2&quot;" />
Run Code Online (Sandbox Code Playgroud)

但是,在查看构建日志时,您看到的是MSBuild将常量分开,并且不会像您期望的那样将值组合在一起 - 类似于:

Task "MSBuild" Global Properties:
Configuration=MyConfig
Platform=x86
DefineConstants="SOMETHING=1
SOMETHINGELSE=2"
Run Code Online (Sandbox Code Playgroud)

因此,当candle尝试使用这些常量时,它通常会响应"错误CNDL0150:未定义的预处理器变量'$(var.SOMETHINGELSE)'.这意味着MSBuild任务无法正确处理值中包含多个'='的属性当在引号内分组时.如果没有将属性值分组在引号中,它们显然应被视为单独的属性,而不是单个值.

解决方法:

为了解决此问题,您需要直接调用MSBuild.exe并手动将这些值传递给它.

msbuild.exe /p:Configuration=MyConfig /p:Platform=x86 /p:DefineConstants="SOMETHING=1;SOMETHINGELSE=2" YourSolution.sln
Run Code Online (Sandbox Code Playgroud)

这将使您的常量按照您希望的方式工作,而无需重新设计您的WiX安装项目.

注意:如果您只使用一个常量,您仍然可以像这样使用MSBuild任务:

<MSBuild Projects="YourSolution.sln" Properties="Configuration=MyConfig;Platform=x86;DefineConstants=&quot;SOMETHING=1&quot;" />
Run Code Online (Sandbox Code Playgroud)

  • 有这样使用MSBuild任务,而不是调用exe文件的方式:http://stackoverflow.com/questions/506687/defining-multiple-values-in-defineconstants-in-msbuild-element/4280454#4280454 (2认同)

Ror*_*eod 13

问题在于将名称 - 值对传递给MSBuild任务,然后使MSBuild正确解析它们,以便将它们传递给Candle任务.似乎MSBuild可以处理简单名称列表或单个名称 - 值对,但不能处理对列表.

我的解决方案是在传递到MSBuild任务时转义列表,并在转到Candle任务时再次取消它.

在MSBuild文件中,在属性中定义对,如下所示:

<PropertyGroup>
    <WixValues>
        One=1;
        Two=2;
        Three=3;
    </WixValues>
</PropertyGroup>
Run Code Online (Sandbox Code Playgroud)

当您调用MSBuild任务时,请转义该属性(需要MSBuild 4):

<MSBuild 
    Projects="setup.wixproj"
    Properties="WixValues=$([MSBuild]::Escape($(WixValues)))" />
Run Code Online (Sandbox Code Playgroud)

unescaping必须在wixproj文件中完成,但不需要手动编辑文件.只需打开项目的属性,转到Build选项卡,并在其中显示"Define preprocessor variables",放置:

$([MSBuild]::Unescape($(WixValues)))
Run Code Online (Sandbox Code Playgroud)

即使该框中已有其他变量,这也有效; 只需将其与分号一起添加到列表中即可.

您将在MSBuild日志中看到该candle.exe工具正确接收参数:

candle.exe -dOne=1 -dTwo=2 -dThree=3 -dConfiguration=Release...
Run Code Online (Sandbox Code Playgroud)


小智 5

我仍然遇到了很多麻烦,但上面的每个答案都对我的解决方案做出了贡献,所以我想分享。

环境:TFS Build Server 2010 - Powershell 调用 MSBuild.exe Wix 3.6 安装在构建服务器上

目标是将构建版本号和 5 个目录传递到 MSBuild,以便 Candle.exe 能够正确接收它们

构建在构建结束时调用命令文件,该命令文件包含调用 powershell 脚本来构建 Wix 安装程序的步骤。它传入构建的版本号以及源目录和输出目录(输出是 UNC 文件共享引用 \tfsbuildserver..)

要使其正常工作,请在 Powershell ps1 文件中,

  • 使用以双“开头的单个 /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
    
    Run Code Online (Sandbox Code Playgroud)
  • 在 wixproj 文件中,我们必须取消转义(在底部,它说取消注释才能修改)

      <Target Name="BeforeBuild">
          <CreateProperty Value="$([MSBuild]::Unescape($(DefineConstants)))">
             <Output TaskParameter="Value" PropertyName="DefineConstants" />
          </CreateProperty>
      </Target>
    
    Run Code Online (Sandbox Code Playgroud)
  • 另请注意,在 Visual Studio 中,我将使用调试设置,并且可以在“构建”选项卡的“定义预处理器变量”中为这些值设置默认值

  • 在发布设置中,此项应为空,因为它将在上面的命令行中传递。