我有一个生成cs文件的批处理文件。新的cs文件存储在我的项目解决方案之一中。
这是我的msbuild任务的摘要:
<Target Name="MyDummyGenerator" BeforeTargets="Build">
<Message Text="Generating file" />
<Exec Command="./path_to_batch_file/dummy.bat" ContinueOnError="false" />
</Target>
问题在于,我生成的文件未在要编译的文件中列出,也不属于程序集的一部分。尝试使用<Compile Include="MyGeneratedFile.cs">
将此文件隐式添加到csproj文件后,出现此错误(MyGeneratedFile.cs是从批处理文件写入的文件:“ 包含重复的'Content'项。默认情况下,.NET SDK包含项目目录中的'Content'项“。
BTW-再次编译时,生成文件是程序集的一部分,但这是因为在开始整个构建步骤之前,该文件位于项目源中...
我什至试图在PreBuild事件中运行它都没有运气。
使用msbuild生成c#代码的正确方法是什么?P.S我正在使用.net Framework 4.7.1
我想这篇文章回答了这个问题:https://mhut.ch/journal/2015/06/30/build-time-code-generation-in-msbuild
简而言之,您需要在编译(或智能感知)开始之前钩住CoreCompile目标以生成文件,并在目标内部生成Compile项。有关如何在构建过程中创建项目的详细信息,请参见此文档:https://docs.microsoft.com/en-us/visualstudio/msbuild/msbuild-items?view=vs-2019#create-items-during-execution
此外,您应将文件生成到中间输出(obj文件夹),而不是在源文件中生成,以免造成混乱。在下面的示例中,输入和输出主要在这里供MSBUILD了解文件更改时要刷新的内容。
<Target Name="UpdateGeneratedFiles"
DependsOnTargets="_UpdateGeneratedFiles"
Condition=="'@(ResourceFile)' != ''"
>
<ItemGroup>
<Compile Include="$(IntermediateOutputDir)GeneratedFile.g.cs" />
<!-- see https://mhut.ch/journal/2016/04/19/msbuild_code_generation_vs2015
<FileWrites Include="$(IntermediateOutputDir)GeneratedFile.g.cs" />
-->
</ItemGroup>
</Target>
<Target Name="_UpdateGeneratedFiles"
Inputs="$(MSBuildProjectFile);@(ResourceFile)"
Outputs="$(IntermediateOutputDir)GeneratedFile.g.cs"
>
<FileGenerationTask
Inputs="@(ResourceFile)"
Output="$(IntermediateOutputDir)GeneratedFile.g.cs"
>
</Target>