背景:StyleCop抱怨自动生成的文件格式不佳,当我尝试构建项目时会导致许多警告。自动生成的文件位于我项目的obj/
目录中,我想创建一个MSBuild任务,在编译之前将// <auto-generated/>
添加到此文件中(但是在生成之后),以便StyleCop不会抱怨。
问题:我有以下MSBuild代码
<!-- StyleCop complains about a file that's auto-generated by the designer,
so we need to prepend 'auto-generated' to it beforehand. -->
<Target Name="BeforeCompile" DependsOnTargets="MarkGeneratedFiles" />
<Target Name="MarkGeneratedFiles">
<PropertyGroup>
<GeneratedFilePath>$(MSBuildThisFileDirectory)obj\$(Configuration)\$(TargetFramework)\$(MSBuildProjectName).Program.cs</GeneratedFilePath>
</PropertyGroup>
<InsertIntoFile FilePath="$(GeneratedFilePath)" LineNumber="1" Text="// <auto-generated/>" />
</Target>
<!-- Code taken from http://stackoverflow.com/a/21500030/4077294 -->
<UsingTask
TaskName="InsertIntoFile"
TaskFactory="CodeTaskFactory"
AssemblyFile="$(MSBuildToolsPath)\Microsoft.Build.Tasks.v4.0.dll">
<ParameterGroup>
<FilePath ParameterType="System.String" Required="true" />
<LineNumber ParameterType="System.Int32" Required="true" />
<Text ParameterType="System.String" Required="true" />
</ParameterGroup>
<Task>
<Using Namespace="System" />
<Using Namespace="System.IO" />
<Code Type="Fragment" Language="cs">
<![CDATA[
// By tradition, text file line numbering is 1-based
var lines = File.Exists(FilePath)
? File.ReadAllLines(FilePath).ToList()
: new List<String>(1);
lines.Insert(Math.Min(LineNumber - 1, lines.Count), Text);
File.WriteAllLines(FilePath, lines);
return true;
]]>
</Code>
</Task>
</UsingTask>
我要修改的文件的文件名为obj/Debug/netcoreapp1.0/BasicCompiler.Tests.Program.cs
。在上面的代码段中,我有一个BeforeCompile
目标,该目标取决于MarkGeneratedFiles
,它继续尝试在该文件的第一行之前插入// <auto-generated/>
。
我已经测试过,如果生成的文件已经存在,这似乎工作正常。但是,如果我删除obj/
目录或从其他计算机构建,我会收到此错误:
"C:\cygwin64\home\james\Code\cs\BasicCompiler\src\BasicCompiler.Tests\BasicCompiler.Tests.csproj" (default target) (1) ->
(MarkGeneratedFiles target) ->
C:\cygwin64\home\james\Code\cs\BasicCompiler\src\BasicCompiler.Tests\BasicCompiler.Tests.csproj(68,5): error MSB4018: The "InsertIntoFile" task failed unexpectedly.\r
C:\cygwin64\home\james\Code\cs\BasicCompiler\src\BasicCompiler.Tests\BasicCompiler.Tests.csproj(68,5): error MSB4018: System.IO.DirectoryNotFoundException: Could not find
a part of the path 'C:\cygwin64\home\james\Code\cs\BasicCompiler\src\BasicCompiler.Tests\obj\Debug\netcoreapp1.0\BasicCompiler.Tests.Program.cs'.\r
基本上似乎目标是在生成文件之前运行,因此没有任何内容可以在文本前添加。有没有办法在生成此文件后运行,但编译之前?
附加说明:到目前为止,我查看了所有特殊目标名称here,并尝试同时使用BeforeBuild
和BeforeCompile
。
另外,由于我使用的是“new”StyleCop,因此我无法将<ExcludeFromStyleCop>
放入项目文件中。见https://github.com/DotNetAnalyzers/StyleCopAnalyzers/issues/1145
答案 0 :(得分:1)
我设法解决了这个问题;请参阅@ stijn的超级有用的评论here。
首先,我从命令行运行msbuild /v:detailed
。这增加了MSBuild的详细程度,因此它可以让您更详细地了解正在进行的操作,例如:您可以看到正在运行的每个目标的名称。
我在日志中搜索了生成该文件的目标的名称。就我而言,结果是GenerateProgramFiles
。
我使用AfterTargets="GenerateProgramFiles"
标记了我的自定义目标,因此它在生成文件后运行。