我正在试着写一个代码生成工具。对于这个工具,重要的是生成的代码在构建之前是可用的(例如,对于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时,它会立即反映在IntelliSense中(就像通常的后台操作一样),依此类推。
但是,假设不是直接编译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,特别是“设计时IntelliSense”部分。我非常确定我的代码满足所有这些标准。我遗漏了什么?
发布于 2013-05-01 08:44:50
在对调试器进行了几天的实验和探索之后,我想我已经找到了答案,不幸的是,答案是这是不可能的(至少不是以一种明确支持的方式--我确信有办法欺骗系统)。
当加载项目时,当项目本身发生更改(添加/删除文件、更改构建操作等)时,将执行IntelliSense构建(csproj.dll!CLangCompiler::RunIntellisenseBuild)。此构建将运行任务,直到并包括Csc任务。Csc不会正常执行,而只是将其输入反馈给它的宿主(Visual Studio)。
从这一点开始,Visual Studio将跟踪作为Sources提供给Csc任务的文件。它将监视这些文件的更改,并在更改时更新IntelliSense。因此,在我的示例中,如果我手动编辑Bar.g.cs,这些更改将被采用。但是,在项目更改或显式请求生成之前,不会再次运行生成任务本身。
所以,我想,这是令人失望的,但并不令人惊讶。它还解释了我一直想知道的另一件事--带有代码隐藏的XAML文件往往有一个自定义工具操作MSBuild:Compile,大概就是因为这个原因。
我将把这个标记为答案,但我希望有人告诉我我错了,我漏掉了一些东西。
https://stackoverflow.com/questions/16267032
复制相似问题