我正在尝试编写代码生成工具。对于此工具,在构建之前生成的代码是可用的(即,对于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”部分。我很确定我的代码符合所有这些标准。我错过了什么?
答案 0 :(得分:6)
在调试器中进行了几天的实验和调试后,我认为我找到了答案,不幸的是,答案是这是不可能的(至少不是以明确支持的方式 - 我敢肯定有欺骗系统的方法。)
加载项目时,以及项目本身更改(添加/删除文件,更改构建操作等)时,将执行IntelliSense构建(csproj.dll!CLangCompiler::RunIntellisenseBuild
)。此构建将运行任务,包括Csc
任务。 Csc
将无法正常执行,而只是将其输入反馈回其主机(Visual Studio)。
从此时起,Visual Studio会将Sources
给出的文件跟踪到Csc
任务。它将监视这些文件的更改,并在更改时更新IntelliSense。因此,在我的示例中,如果我手动编辑Bar.g.cs
,则会选择这些更改。但是,在项目更改或显式请求构建之前,构建任务本身不会再次运行。
所以,这是令人失望的,但我觉得并不奇怪。它还解释了我一直想知道的其他事情 - 带有代码隐藏的XAML文件往往具有MSBuild:Compile
的自定义工具操作,可能正是出于这个原因。
我打算将此作为答案,但我很想被告知我错了,我错过了一些东西。