使用MSBuild生成C#

问题描述 投票:0回答:1

我有一个生成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

c# .net msbuild code-generation msbuild-task
1个回答
0
投票

我想这篇文章回答了这个问题: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>
© www.soinside.com 2019 - 2024. All rights reserved.