【发布时间】:2012-09-11 22:12:00
【问题描述】:
我有一个 C# 项目,它采用几种不同的配置构建。某些源文件应始终包含在内,而某些源文件仅在某些配置中包含。到目前为止,我一直在使用 #if ... #endif 围绕整个文件执行此操作,但我希望创建一个小扩展来更好地执行此操作。
我创建了一个扩展,可以将项目添加到文件的上下文菜单中,但我找不到任何方法来设置项目文件中项目节点上的Condition 属性。
我查看了EnvDTE.ProjectItem 接口的Properties 集合,但在那里看不到任何有用的东西(除了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(),但它会将类似的子元素添加到靠近顶部的PropertyGroup 部分,而不是添加到项目节点。
我查看了“项目子类型/风味”,但看起来它只会让我获得另一个 IVsBuildPropertyStorage,这似乎没有用。它们看起来确实能够处理很多复杂的事情,但有关该主题的文档似乎很少且含糊不清。
我看过一些描述如何使用 MSBuild 程序集直接加载和操作项目文件的帖子,但我不确定 什么时候 在不混淆 Visual Studio 和潜在的情况下这样做是否安全丢失更改,因为 VS 在检测到项目文件发生更改时会提示重新加载。
作为最后一个想法,我考虑过在 Compile 和 None 之间操作 BuildAction 属性,但这听起来我的扩展程序要正确维护它可能需要做很多工作,使其与每个例如,用户在 IDE 中切换配置的时间。
有没有人对这种事情有任何经验可以给我任何建议,或者我应该放弃希望并坚持在任何地方手动添加#if指令?
【问题讨论】:
-
可能的方法是,1)为每个配置单独的项目文件; 2) 一个核心项目,具有基于基本配置的扩展项目。与您现在尝试实现的目标相比,它们更容易管理。
-
简单地执行#ifs 有一个论据:大多数人都知道它是如何工作的。或者至少比了解 MSBuild 的人多得多。我喜欢 MSBuild 黑客,但我最不想做的就是花一个小时试图弄清楚为什么这个文件没有被编译,只是发现项目文件中有魔法。
-
@JasonMalinowski:有问题的代码是部分类的集合,这些部分位于名为 Class.cs、Class.Client.cs 和 Class.Server.cs 的文件中,所以不是太令人困惑。必须添加所有 #ifs 只是很乏味 - 有很多文件要做和维护。
标签: msbuild visual-studio-extensions vspackage