正确的方法使用MSBuild Task通过Intellisense

时间:2018-11-01 14:06:37

标签: c# visual-studio visual-studio-templates vssdk

上下文

对于某些项目,我们一直在尝试直接从Visual Studio生成代码。基本思想是可以创建一堆(.foo)文件,并且每个(.foo)文件都对应一个生成的(.foo.cs)文件。

该过程基本上如下:

  1. 在构建期间,将收集所有.foo文件。
  2. 发生了一些转变。请注意,某些转换需要来自所有.foo文件的信息。
  3. 对于每个.foo文件,都会发出带有部分类的.foo.cs文件。

通常,我会为此创建一个文件生成器(自定义工具),但是,在这种情况下,我想知道文件名始终为.foo.cs,而且似乎没有可以通过单个文件生成器控制的方式。同样,构建需要来自多个文件的信息这一事实使我选择了另一种方法。

因此,我创建了一个MS Build Task,并将其注册在csproj中:

<UsingTask AssemblyFile="C:\Projects\FooTool\bin\Debug\FooBuildTool.dll"
           TaskName="FooBuildTool.FooTool" />
<Target Name="Foo" BeforeTargets="BeforeBuild" 
        Condition="'$(MSBuildProjectExtension)' == '.csproj'">
    <FooTool Language="C#" ProjectFolder="$(ProjectDir)" 
             ProjectName="$(ProjectName)" Sources="@(Foo)">
        <Output ItemName="FooCompile" TaskParameter="ComputedSources" />
    </FooTool>
    <ItemGroup>
        <Compile Include="@(FooCompile->'%(Outputs)')" />
    </ItemGroup>
</Target>

从代码生成可以正常工作的意义上讲,这可以正常工作,并且可以生成所有必需的.cs文件。

请注意,如果在单击“构建”之前Intellisense不起作用-很好。

情况

现在的问题是.foo.cs文件的Intellisense已损坏,我正在寻找一种解决此问题的方法。

我试图通过进一步更改.csproj文件来解决此问题:

<Compile Include="Test.foo.cs">
  <AutoGen>True</AutoGen>
  <DesignTime>True</DesignTime>
  <DependentUpon>Test.foo</DependentUpon>
</Compile>

...

<Foo Include="Test.foo" Generator="Foo" LastGenOutput="Test.foo.cs" />

在文件现在显示在Visual Studio的解决方案资源管理器中的意义上,这似乎可行。

但是,我不知道如何自动创建它,也找不到任何文档或有关它的示例。我猜这与构建合适的VSTemplate有关吗?

问题

解决此问题的正确方法是什么?例如。我如何确保生成的文件显示在Visual Studio中,以便Intellisense可以拾取它们?

1 个答案:

答案 0 :(得分:1)

我有类似的问题:我有一个任务,该任务基于模板生成一些.cs文件。该项目的目标是dotnet core 3.1

首先我写了

<Target Name="GenerateEnvFiles" BeforeTargets="BeforeBuild;BeforeClean">

构建成功,但智能感知却没有。

我正在检查其他来源,发现an article on msdn他们说:

设计时IntelliSense 要在生成生成输出程序集之前获得Visual Studio中的IntelliSense支持,必须满足以下条件:

必须有一个名为Compile的目标。

尽管设置BeforeTargets=...;Compile无效,但设置CoreCompile却对我有用,现在build和intellisense都可以正常工作。

我假定智能感知分析器具有自己的工作流程,其中使用了除BeforeBuild之外的其他目标。但是我没有找到有关它确切使用的目标的任何细节。(例如,从上面的msdn文章中,我认为BeforeTargets="Compile"应该有效,而无效)