2

我有一个 C# 项目,它是用几种不同的配置构建的。某些源文件应始终包含在内,而某些源文件仅在某些配置中包含。到目前为止,我一直#if ... #endif在对整个文件进行此操作,但我希望创建一个小扩展来以更好的方式执行此操作。

我创建了一个扩展,将项目添加到文件的上下文菜单中,但我找不到任何方法来设置Condition项目文件中项目节点的属性。

我查看Properties了界面的集合EnvDTE.ProjectItem,但在那里看不到任何有用的东西(除了 BuildAction ......我会回到那个)。

然后我尝试IVsBuildPropertyStorage在该项目上获得一个并打电话给SetItemAttribute(). 这确实将信息添加到项目文件中,但作为这样的子元素:

<ItemGroup>
  <Compile Include="Program.cs">
    <Condition>%27%24%28Configuration%29%27==%27Debug%27</Condition>
  </Compile>
</ItemGroup>

当我试图实现的是:

<ItemGroup>
  <Compile Include="Program.cs" Condition="'$(Configuration)'=='Debug'" />
</ItemGroup>

还有一个IVsBuildPropertyStorage.SetPropertyValue()but 将类似的子元素添加到PropertyGroup靠近顶部的部分,而不是添加到 item 节点。

我看过'Project Subtypes/Flavors',但看起来它只会让我得到另一个 IVsBuildPropertyStorage,这似乎没有用。它们看起来确实能够处理很多复杂的事情,但有关该主题的文档似乎很少且含糊不清。

我看过一些描述如何使用 MSBuild 程序集直接加载和操作项目文件的帖子,但我不确定什么时候可以安全地这样做,而不会混淆 Visual Studio 并可能丢失更改,因为 VS 会在它提示重新加载时检测对项目文件的更改。

作为最后一个想法,我考虑过在和BuildAction之间操作属性,但这听起来我的扩展需要做很多工作才能正确维护,例如每次用户在 IDE 中切换配置时都要保持同步。CompileNone

有没有人对这种事情有任何经验可以给我任何建议,还是我应该放弃希望并坚持在#if任何地方手动添加指令?

4

2 回答 2

0

您可能想探索您提到的 MSBuild 选项。

您实际上不必从文件中加载 MSBuild 项目,因为 Visual Studio 为您提供了一种直接访问 MSBuild 项目的方法,即:

string projectPath = projectItem.ContainingProject.FullName;
MsBuildProject project = ProjectCollection.GlobalProjectCollection.GetLoadedProjects(projectPath);
var compileItems = project.GetItems("Compile");

从那里您可以找到您的特定项目并可能添加条件属性,尽管我自己没有尝试过此步骤(如果这不起作用,您可能不得不尝试修改project.Xml属性下的项目元素)。

然后您可以调用project.Save(),这不应该触发“重新加载项目?” 对话框,因为 MsBuild 项目实例链接到 Visual Studio 项目层次结构的方式。

但是,您可能希望强制 Visual Studio 重新加载项目,因为如果您切换构建配置(例如在调试和发布之间),MSBuild 引擎可能不会在构建期间重新评估您的项目条件。可以在此处找到以编程方式执行此操作的代码:

修改基础文件后,如何以编程方式刷新/重新加载 VS 项目?

于 2012-09-14T07:48:45.467 回答
0

不幸的是,我从来没有时间去坚持创建扩展的最初目标,但是我确实使用lex-li的建议实现了我所需要的:每个配置使用单独的项目文件。

由于项目文件都可以驻留在同一个目录中,因此只需使用解决方案资源管理器中的“从项目中包含/排除”上下文菜单项来选择包含哪些文件很容易。这种方式也不需要文件链接,我之前尝试过,发现管理起来非常耗时。

如果您有类似的需求,部分方法也值得一看。它们允许您在一个地方定义方法的签名,但可以选择在其他地方实现它。如果你不实现它,编译器不会生成调用。

关于扩展的最初想法,我怀疑Daniel Nolan 的答案是朝着正确的方向发展,但不幸的是我没有尝试过。

于 2015-02-22T16:58:51.783 回答