如何阻止 MSBuild 用正斜杠替换反斜杠?

rmu*_*unn 6 msbuild msbuild-4.0

MSBuild 通常会用正斜杠替换构建文件中的反斜杠(通常在路径中找到),这在处理跨平台项目时很有帮助。但我有一个任务,我不希望 MSBuild 触及我的反斜杠:我们的构建中有一个自定义任务,它采用正则表达式和替换任务,并更新文件。(我使用它来更新 AssemblyInfo.cs 文件中的版本号,从 获取版本号git describe。有一个 TeamCity 构建功能,只要我能够控制它的运行时间,它就可以工作,但这是一个不同的故事 - 足以说在我的 MSBuild 文件中执行此操作看起来是目前最好的方法)。

我的问题是,MSBuild 通过在我传递给自定义任务的属性中用正斜杠替换反斜杠来“帮助”我,这对我的正则表达式造成了严重破坏。我写的:

<FileUpdate File="$(RootDir)/GlobalAssemblyInfo.cs"
            Regex='AssemblyFileVersion\("[^"]+"\)'
            ReplacementText='AssemblyFileVersion("$(VersionNumber)")' />
Run Code Online (Sandbox Code Playgroud)

我在构建日志中得到了什么:

error : Did not manage to replace 'AssemblyFileVersion/("[^"]+"/)' with 
        'AssemblyFileVersion/("1.1.0.92"/)'
Run Code Online (Sandbox Code Playgroud)

请注意我的正则表达式中的反斜杠是如何变成正斜杠的?是的,这不会与我的 AssemblyInfo.cs 文件中的任何内容匹配。

我已经能够通过完全避免在正则表达式中使用反斜杠来解决这个问题,如下所示:

<FileUpdate File="$(RootDir)/GlobalAssemblyInfo.cs"
            Regex='AssemblyFileVersion[(]"[^"]+"[)]'
            ReplacementText='AssemblyFileVersion("$(VersionNumber)")' />
Run Code Online (Sandbox Code Playgroud)

但这并不适用于所有情况。迟早我会需要一个正则表达式 with \,或者其他一些反斜杠表达式,然后我就会陷入困境。在此之前,我真的很想弄清楚如何告诉 MSBuild“停止帮助我!我说反斜杠,我真正的意思是反斜杠,而不是正斜杠,在这个 ONE 属性中。您可以使用其他属性“帮助”我你喜欢,但别管这个!” 有任何想法吗?

awa*_*tar 1

您可以创建自己的替换文本任务,并通过简单地将 / 更改为 \ 或使用其他更独特的标记来控制错误替换的字符。

<UsingTask TaskName="ReplaceFileText" TaskFactory="CodeTaskFactory" AssemblyFile="$(MSBuildToolsPath)\Microsoft.Build.Tasks.Core.dll">
<ParameterGroup>
    <InputFilename ParameterType="System.String" Required="true" />
    <MatchExpression ParameterType="System.String" Required="true" />
    <ReplacementText ParameterType="System.String" Required="true" />
</ParameterGroup>
<Task>
    <Reference Include="System.Core" />
    <Using Namespace="System" />
    <Using Namespace="System.IO" />
    <Using Namespace="System.Text.RegularExpressions" />
    <Code Type="Fragment" Language="cs">
        <![CDATA[
            File.WriteAllText(
                InputFilename,
                Regex.Replace(File.ReadAllText(InputFilename), MatchExpression.Replace('/', '\\'), ReplacementText)
            );
          ]]>
    </Code>
</Task>
Run Code Online (Sandbox Code Playgroud)