1

我有一个 msbuild 脚本,它使用 Exec 标记启动另一个 MSBuild 命令,包括具有多个值的 DefineConstants 属性。由于该属性有多个值,因此我使用此问题中描述的技术直接调用 MSBuild.exe(不使用 MSBuild 标记)并将值括在引号中。

但是,我现在需要在其中一个值中嵌入一个特殊符号,我正在尝试使用代码¯(注册商标®)

问题是特殊字符代码必须以分号结尾,但是当我嵌入分号时,msbuild 将其读取为值分隔符。我似乎找到了一种有效的方法来转义分号并让它仍然显示在 end 参数值中。

我的问题是:如何将特殊字符嵌入到我的构建参数中?

为了提高可读性,我在示例中将值移动到变量中,但这不是必需的。

文件:TopLevelBuildScript.proj

  <Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
    <Target Name="BuildWithSpecialChar">
    <ItemGroup>
      <!-- Note: %3B is the escape code for semicolon -->
      <MyProductName Include="Trademarked&amp;#174%3B Product" />
      <OtherProperty Include="foo" />
    </ItemGroup>

   <Exec Command="msbuild.exe subBuildScript.proj /p:DefineConstants=&quot;MyProductName=@(MyProductName);OtherVar=@(foo);AnotherVar=asdf;&quot; " />
    </Target>
  </Project>

执行时,上面会产生命令行:

msbuild.exe subBuildScript.proj /p:DefineConstants="MyProductName=Trademarked&#174; Product;OtherVar=foo;AnotherVar=asdf;"

最终定义了在分号处拆分产品名称的常量:

MyProductName=Trademarked&#174
Product
OtherVar=foo
AnotherVar=asdf

注意:我也尝试使用 %25 作为百分号:

<MyProductName Include="Trademarked&amp;#174%253B Product" />

但这给了我:

MyProductName=Trademarked&#174B Product
OtherVar=foo  
AnotherVar=asdf

更新

事实证明,问题不在于 MSBuild,而在于 WiX 解析参数的方式(我的 subBuildScript 使用 WiX)。我没有考虑到这一点,所以在我的原始帖子中没有提到它。

最终,我根据另一个问题的答案提出了一个解决方案:

<PropertyGroup>   
  <WixValues>
    <MyProductName>Trademarked® Product<MyProductName>
    <OtherProperty>foo"</OtherProperty>
  </WixValues>
</PropertyGroup>
<MSBuild
    Projects="subProjectScript.proj"
    Properties="Configuration=Release;WixValues=$([MSBuild]::Escape($(WixValues)))"
    Targets="Clean;Rebuild"
    ContinueOnError="false"
    StopOnFirstFailure="true">
</MSBuild>

并取消转义 subProjectScript.proj 中的值,如另一个答案中所述。

4

1 回答 1

1

首先,MSBuild 文件是 XML,您可以将其编码为 UTF-8,因此您应该能够直接在 MSBuild 脚本中复制/粘贴商标字符,而无需转义.

如果您不能采用这种方法,请不要逃避 & 符号。MSBuild 脚本中有两个级别的转义内容。第一个是 XML 编码,以便可以使用对 XML 敏感的字符(<&),并且您仍然可以拥有安全的 XML。当 MSBuild 读入文件时,XML 转义序列不会转义。在该过程之后,MSBuild 然后执行它自己的反转义(即%3B分号)。

因为您在&amp;XMl 转义序列的开头使用,所以 XML 处理器将其解释为文字& 符号,而不是表示转义序列的特殊 XML & 符号。将MyProductName项目组的值更改为:

<MyProductName Include="Trademarked&#174; Product" />

由于MyProductName似乎是一个标量值,而不是一个列表,我会使用一个属性来代替:

<PropertyGroup>
  <MyProductName>Trademarked® Product</MyProductName>
</PropertyGroup>

在您的Exec任务中,您可以像这样使用它:

<Exec Command="msbuild.exe subBuildScript.proj /p:DefineConstants=&quot;MyProductName=$(MyProductName);OtherVar=@(foo);AnotherVar=asdf;&quot; " />
于 2012-09-11T03:08:09.247 回答