无条件包含该文件应该可以工作。例如,在 Microsoft.CSharp.targets 导入之后的默认 C# 项目模板中使用这些行:
<ItemGroup>
<MyInput Include="in.txt" />
</ItemGroup>
<PropertyGroup>
<MyOutput>Generated.cs</MyOutput>
</PropertyGroup>
<Target Name="MyCodeGen" BeforeTargets="PreBuildEvent" DependsOnTargets="ResolveReferences"
Inputs="@(MyInput);$(MSBuildThisFileFullPath)"
Outputs="$(MyOutput)">
<ReadLinesFromFile File="@(MyInput)">
<Output TaskParameter="Lines" ItemName="MyInputlines"/>
</ReadLinesFromFile>
<Message Text="CODEGEN lines @(MyInputlines)" />
<WriteLinesToFile File="$(MyOutput)" Lines="@(MyInputlines)" Overwrite="True" />
</Target>
<ItemGroup>
<Compile Include="$(MyOutput)"/>
</ItemGroup>
在命令行上运行 msbuild /v:d 的结果是(仅显示 MyCodeGen Target 的输出):
第一次运行的输出(Generated.cs 还不存在):
Target "MyCodeGen" in project "my.csproj" (target "PreBuildEvent" depends on it):
Building target "MyCodeGen" completely.
Output file "Generated.cs" does not exist.
Using "ReadLinesFromFile" task from assembly "Microsoft.Build.Tasks.Core, Version=15.1.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a".
Task "ReadLinesFromFile"
Done executing task "ReadLinesFromFile".
Task "Message"
CODEGEN lines using System;
Done executing task "Message".
Using "WriteLinesToFile" task from assembly "Microsoft.Build.Tasks.Core, Version=15.1.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a".
Task "WriteLinesToFile"
Done executing task "WriteLinesToFile".
Done building target "MyCodeGen" in project "my.csproj".
第二次/第三次/...运行的输出:
Target "MyCodeGen" in project "my.csproj" (target "PreBuildEvent" depends on it):
Skipping target "MyCodeGen" because all output files are up-to-date with respect to the input files.
Input files: in.txt;my.csproj
Output files: Generated.cs
Done building target "MyCodeGen" in project "my.csproj".
修改in.txt后生成的输出:
Target "MyCodeGen" in project "my.csproj" (target "PreBuildEvent" depends on it):
Building target "MyCodeGen" completely.
Input file "in.txt" is newer than output file "Generated.cs".
Using "ReadLinesFromFile" task from assembly "Microsoft.Build.Tasks.Core, Version=15.1.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a".
Task "ReadLinesFromFile"
Done executing task "ReadLinesFromFile".
Task "Message"
CODEGEN lines using System.Linq;
Done executing task "Message".
Using "WriteLinesToFile" task from assembly "Microsoft.Build.Tasks.Core, Version=15.1.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a".
Task "WriteLinesToFile"
Done executing task "WriteLinesToFile".
Done building target "MyCodeGen" in project "my.csproj".
在此之后运行的输出:
Target "MyCodeGen" in project "my.csproj" (target "PreBuildEvent" depends on it):
Skipping target "MyCodeGen" because all output files are up-to-date with respect to the input files.
Input files: in.txt;my.csproj
Output files: Generated.cs
Done building target "MyCodeGen" in project "my.csproj".
如果这对您不起作用,例如,您用于生成文件的过程可能无法与 msbuild 配合使用,因为它没有正确更新时间戳。例如。仅复制比项目文件更早的现有文件会导致 Generated.cs 的时间戳早于 $(MSBuildThisFileFullPath) 输入,因此目标将始终运行。