Visual Studio如何决定何时以及如何重建IntelliSense?

时间:2013-04-28 19:44:15

标签: visual-studio msbuild intellisense

我正在尝试编写代码生成工具。对于此工具,在构建之前生成的代码是可用的(即,对于IntelliSense),这一点很重要。我知道Visual Studio将至少部分地自动评估项目构建计划以生成IntelliSense,但我找不到有关细节的更多信息。

作为一个更简单的例子,假设我想要使用构建操作None获取所有项目并进行编译。我有一个这样的项目:

<Project [...]>
  [...]
  <Compile Include="Foo.cs" />
  <None Include="Bar.cs" />
</Project>

获取Bar.cs编译的一种方法是将以下内容添加到项目中:

<PropertyGroup>
  <CoreCompileDependsOn>
    $(CoreCompileDependsOn);IndirectCompile
  </CoreCompileDependsOn>
</PropertyGroup>
<Target Name="IndirectCompile">
  <CreateItem Include="@(None)">
    <Output ItemName="Compile" TaskParameter="Include" />
  </CreateItem>
</Target>

如果我这样做,Visual Studio的行为基本上与Bar.cs开始Compile操作的行为相同。 IntelliSense完全可用;如果我在Bar.cs进行了更改,那么当我正在编辑Foo.cs时,它会立即反映出来(好,就像背景操作通常那样直接在智能感应中),依此类推。

但是,我不想直接编译None条目,而是将其复制到obj目录,然后从那里编译。我可以通过将IndirectCompile目标更改为此来执行此操作:

<Target Name="IndirectCompile" 
        Inputs="@(None)"
        Outputs="@(None->'$(IntermediateOutputPath)%(FileName).g.cs')"
>
  <Copy SourceFiles="@(None)"
        DestinationFiles="@(None->'$(IntermediateOutputPath)%(FileName).g.cs')"
  >
    <Output TaskParameter="DestinationFiles" ItemName="Compile" />
  </Copy>
</Target>

执行此操作会导致IntelliSense停止更新。该任务适用于构建,依赖性分析和增量构建工作,Visual Studio只是在保存输入文件时停止自动运行它。

因此,这导致标题问题:Visual Studio如何选择为IntelliSense运行目标?我发现的唯一官方文档是this,特别是“Design-Time IntelliSense”部分。我很确定我的代码符合所有这些标准。我错过了什么?

1 个答案:

答案 0 :(得分:6)

在调试器中进行了几天的实验和调试后,我认为我找到了答案,不幸的是,答案是这是不可能的(至少不是以明确支持的方式 - 我敢肯定有欺骗系统的方法。)

加载项目时,以及项目本身更改(添加/删除文件,更改构建操作等)时,将执行IntelliSense构建(csproj.dll!CLangCompiler::RunIntellisenseBuild)。此构建将运行任务,包括Csc任务。 Csc将无法正常执行,而只是将其输入反馈回其主机(Visual Studio)。

从此时起,Visual Studio会将Sources给出的文件跟踪到Csc任务。它将监视这些文件的更改,并在更改时更新IntelliSense。因此,在我的示例中,如果我手动编辑Bar.g.cs,则会选择这些更改。但是,在项目更改或显式请求构建之前,构建任务本身不会再次运行。

所以,这是令人失望的,但我觉得并不奇怪。它还解释了我一直想知道的其他事情 - 带有代码隐藏的XAML文件往往具有MSBuild:Compile的自定义工具操作,可能正是出于这个原因。

我打算将此作为答案,但我很想被告知我错了,我错过了一些东西。