如何使用msbuild替换文件中的字符串?

Nit*_*hin 29 msbuild msbuild-task msbuild-propertygroup msbuild-buildengine

我想在另一个文件xy.xml中使用字符串"我很好"替换文件test.xml中的"how r u"字符串.使用ms build中的正则表达式.

即我必须从一个文件(xy.xml)读取字符串并将其替换为另一个文件test.xml.所以请通过示例提供解决此问题的必要步骤

csh*_*net 86

这不再是必需的......你现在可以将C#注入到项目/构建文件中......

定义自定义任务和参数,如下所示:

<UsingTask TaskName="ReplaceFileText" TaskFactory="CodeTaskFactory" AssemblyFile="$(MSBuildToolsPath)\Microsoft.Build.Tasks.v4.0.dll">
  <ParameterGroup>
    <InputFilename ParameterType="System.String" Required="true" />
    <OutputFilename 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(
                OutputFilename,
                Regex.Replace(File.ReadAllText(InputFilename), MatchExpression, ReplacementText)
                );
          ]]>
    </Code>
  </Task>
</UsingTask>
Run Code Online (Sandbox Code Playgroud)

然后只需像任何其他MSBuild任务一样调用它

<Target Name="AfterBuild">
  <ReplaceFileText 
    InputFilename="$(OutputPath)File.exe.config" 
    OutputFilename="$(OutputPath)File.exe.config" 
    MatchExpression="\$version\$" 
    ReplacementText="1.0.0.2" />
</Target>
Run Code Online (Sandbox Code Playgroud)

上面的示例将"$ version $"替换为输出目录中"File.exe.config"中的"1.0.0.2".

  • 请注意,.NET Core附带的MSBuild版本不支持CodeTaskFactory,因此这不是便携式解决方案。 (2认同)

小智 8

有一种非常简单的方法来替换文件中的字符串:

  <Target Name="Replace" AfterTargets="CoreCompile">
      <PropertyGroup>
          <InputFile>c:\input.txt</InputFile>
          <OutputFile>c:\output.txt</OutputFile>
      </PropertyGroup>
      <WriteLinesToFile
          File="$(OutputFile)"
          Lines="$([System.IO.File]::ReadAllText($(InputFile)).Replace('from','to'))"
          Overwrite="true"
          Encoding="Unicode"/>
  </Target>
Run Code Online (Sandbox Code Playgroud)

请参阅https://docs.microsoft.com/en-us/visualstudio/msbuild/property-functions?view=vs-2019 以探索可内联的 C# 代码。[System.Text.RegularExpressions.Regex]列入名单。

  • 小心 `Encoding="Unicode"`!例如,`app.config` 的默认值是 `Encoding="UTF-8"`,它不适用于 Unicode! (2认同)

Jam*_*mes 6

@csharptest.net的答案很好,但它不适用于 DotNetCore。我会将此添加为评论,但我没有足够的声誉。

在 DotNetCore 上,您必须更新:

  • 任务工厂到“RoslynCodeTaskFactory”
  • 任务程序集到“$(MSBuildToolsPath)\Microsoft.Build.Tasks.Core.dll”
  • 删除对“System.Core”的引用
  • 消费目标必须将“AfterTargets”属性指定为“Build”

其他一切都应该是一样的:

<Project Sdk="Microsoft.NET.Sdk.Web">
  ...

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

  <Target Name="AfterBuildStep" AfterTargets="Build">
    <ReplaceFileText
       InputFilename="$(OutputPath)File.exe.config" 
       OutputFilename="$(OutputPath)File.exe.config" 
       MatchExpression="\$version\$" 
       ReplacementText="1.0.0.2" />
  </Target>
</Project>
Run Code Online (Sandbox Code Playgroud)


Lud*_*dwo 4

编辑:这个答案已经过时了。使用下面的解决方案...

使用 ReadLinesFromFile 任务从 xy.xml 文件获取替换字符串。检查这个

然后使用 xy.xml 中的值作为 FileUpdate 任务的替换字符串。检查这个

并将它们放在一起;)