使用MSBuild将多个值传递给Wix DefineConstants属性
我目前正在MSBuild中集成我的Wix项目。我有必要将多个值传递给Wix项目。一个值将起作用(以下示例中的ProductVersion)使用MSBuild将多个值传递给Wix DefineConstants属性,msbuild,wix,msbuild-task,Msbuild,Wix,Msbuild Task,我目前正在MSBuild中集成我的Wix项目。我有必要将多个值传递给Wix项目。一个值将起作用(以下示例中的ProductVersion) 但是,如何将多个值传递给DefineConstants键?我尝试了所有的“逻辑”分隔符(空格、逗号、分号、管道符号),但都不起作用 有其他人遇到过这个问题吗 不起作用的解决方案: 尝试添加DefineConstants元素无效,因为DefineConstants需要在Properties属性中表示 我想这样的办法应该行得通 <DefineConst
但是,如何将多个值传递给DefineConstants键?我尝试了所有的“逻辑”分隔符(空格、逗号、分号、管道符号),但都不起作用
有其他人遇到过这个问题吗
不起作用的解决方案:
我想这样的办法应该行得通 <DefineConstants>DEBUG;TRACE</DefineConstants> 调试;痕迹 查看这篇博客文章,看看它是否能帮助你。 也请查看此论坛帖子。它解决了与您类似的问题。
为什么要指定DefineContstants=ProductVersion=XXXXXX 对于未赋值的DefineConstants,要么定义了常量(如调试或跟踪),要么未定义。此属性与C#编译器开关有关。你到底想干什么 另外,我不知道你说我的博客文章是“黑客”是什么意思,它被构建了两次才是关键 赛义德·易卜拉欣·哈希米
我的书:问题: MSBuild任务(不是MSBuild.exe,是名为MSBuild的MSBuild任务)无法处理WIX项目使用的多个常量。通常,您会在构建脚本中指定以下属性:
<MSBuild Projects="YourSolution.sln" Properties="Configuration=MyConfig;Platform=x86;DefineConstants="SOMETHING=1;SOMETHINGELSE=2"" />
因此,当candle尝试使用这些常量时,它通常会响应“error CNDL0150:Undefined preducer variable'$(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="SOMETHING=1"" />
我知道MSDN文档充满了错误,有时会产生误导:下面是它对定义状态的说明 定义条件编译器 常量。符号/值对为 用分号分隔,是 通过使用以下命令指定 语法: symbol1=值1;symbol2=值2 该属性相当于 /定义编译器开关 根据MSDN,您可以1.定义多个常量,2.(@Sayed)赋值 但是,我无法使MSBuild任务的此属性的预期行为按预期工作,并推荐Jeff Winn的变通方法,他的帖子应标记为答案。变通方法 假设:
- SomeEnumValue的可能值为 EnumValue1和EnumValue2
<DefineConstants>Debug;use_$(SomeEnumValue)</DefineConstants>
Debug;使用$(SomeEnumValue)
在WiX中:
<?ifdef $(var.use_EnumValue1) ?>
...
<?elseif $(var.use_EnumValue2) ?>
...
<?endif?>
...
...
使用MSBuild任务生成Visual Studio解决方案时,以下内容对我很有用:
<MSBuild Projects="Solution.sln"
Targets="Rebuild"
Properties="Configuration=Debug;DefineConstants=DEBUG%3bTRACE" />
诀窍是使用%3b
来转义;
DefineConstants值中的分隔符。我不确定这是否也适用于=
值。它们可能需要作为%3d
转义,或者根本不起作用
MSBuild元素上还有一个
TargetAndPropertyListSeparators
属性。我找不到它的任何文档,但可以使用它设置一个分隔符,而不是;
当我将以下行包括在.wixproj文件(使用Visual Studio 2010)中时,它们起作用
常数1=Value1;常数2=Value2;常数3=Value3
问题在于将名称-值对传递给MSBuild任务,然后让MSBuild正确解析它们,以便将它们传递给Candle任务。MSBuild似乎可以处理简单名称列表或单个名称-值对,但不能处理对列表
我的解决方案是在将列表传递到MSBuild任务时转义该列表,并在它转到蜡烛任务时再次取消转义该列表 在MSBuild文件中,在如下属性中定义对:
<PropertyGroup>
<WixValues>
One=1;
Two=2;
Three=3;
</WixValues>
</PropertyGroup>
<MSBuild ...
Properties="ProductVersion=%(WixSetups.ISVersion)" />
即使该框中已有其他变量,也可以这样做;只需将其与分号一起添加到列表中即可
您将在MSBuild日志中看到candle.exe
工具正确接收参数:
candle.exe -dOne=1 -dTwo=2 -dThree=3 -dConfiguration=Release...
您可以将其作为参数传递,而不是常量。代码如下所示:
<PropertyGroup>
<WixValues>
One=1;
Two=2;
Three=3;
</WixValues>
</PropertyGroup>
<MSBuild ...
Properties="ProductVersion=%(WixSetups.ISVersion)" />
例如:
<Product Id="*" Name="My Company" Language="1033" Version="$(var.BuildVersion)"... />
这将适用于多个参数。这对我来说很有效,允许我传入带有尚未定义的键值对的项。这不是最优雅的,但我不是一个编码员 msbuild test.proj/p:passedInput=“ProductVersion=45;rt=669;wewanttoknow=test5“
我在实现这一点上仍然有很多困难,但上面的每个答案都为我的解决方案做出了贡献,所以我想与大家分享 环境:TFS生成服务器2010-Powershell调用MSBuild.exe Wix 3.6安装在构建服务器上 目标是将生成版本号和5个目录传递到MSBuild中,以便Candle.exe正确接收它们 生成在生成结束时调用命令文件,该命令文件包括调用powershell脚本以生成Wix安装程序的步骤。它传入生成的版本号以及源目录和输出目录(输出是UNC fileshare引用\tfsbuildserver..) 要使其正常工作,请在Powershell ps1文件中
candle.exe -dOne=1 -dTwo=2 -dThree=3 -dConfiguration=Release...
<MSBuild ... Properties="ProductVersion=%(WixSetups.ISVersion)" />
<DefineConstants>BuildVersion=$(ProductVersion)</DefineConstants>
$(var.BuildVersion)
<Product Id="*" Name="My Company" Language="1033" Version="$(var.BuildVersion)"... />
<?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>
$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
<Target Name="BeforeBuild"> <CreateProperty Value="$([MSBuild]::Unescape($(DefineConstants)))"> <Output TaskParameter="Value" PropertyName="DefineConstants" /> </CreateProperty> </Target>
<MSBuild Projects="MyApplication.sln" Properties="DefineConstants=Sources=$(OutputPath)\MyApplication\;Configuration=$(Configuration);OutDir=$(OutputPath)\WiX\" Targets="Clean;Rebuild" />