通过Visual Studio扩展设置MSBuild“Condition”属性

通过Visual Studio扩展设置MSBuild“Condition”属性,msbuild,visual-studio-extensions,vspackage,Msbuild,Visual Studio Extensions,Vspackage,我有一个C项目,它是建立在几个不同的配置。某些源文件应始终包括在内,有些仅在某些配置中包含。到目前为止我一直在做这件事如果。。。endif处理整个文件,但我希望创建一个小的扩展名,以更好的方式实现这一点 我已经创建了一个扩展,它将一个项添加到文件的上下文菜单中,但是我找不到任何方法在项目文件的项节点上设置条件属性 我已经查看了EnvDTE.ProjectItem接口的Properties集合,但除了BuildAction之外,在那里看不到任何有用的内容。。。我会再谈这个问题 然后我尝试在项目上获

我有一个C项目,它是建立在几个不同的配置。某些源文件应始终包括在内,有些仅在某些配置中包含。到目前为止我一直在做这件事如果。。。endif处理整个文件,但我希望创建一个小的扩展名,以更好的方式实现这一点

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

我已经查看了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指令?

您可能希望探索您提到的MSBuild选项

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

string projectPath = projectItem.ContainingProject.FullName;
MsBuildProject project = ProjectCollection.GlobalProjectCollection.GetLoadedProjects(projectPath);
var compileItems = project.GetItems("Compile");
从那里,您可以找到特定的项并可能添加condition属性,尽管我自己没有尝试过这一步骤,但如果这不起作用,您可能需要尝试修改project.Xml属性下的项目元素

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

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


您可能希望探索您提到的MSBuild选项

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

string projectPath = projectItem.ContainingProject.FullName;
MsBuildProject project = ProjectCollection.GlobalProjectCollection.GetLoadedProjects(projectPath);
var compileItems = project.GetItems("Compile");
从那里,您可以找到特定的项并可能添加condition属性,尽管我自己没有尝试过这一步骤,但如果这不起作用,您可能需要尝试修改project.Xml属性下的项目元素

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

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


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

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

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


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

不幸的是,我从来没有时间 e最初的目标是创建一个扩展来实现这一点,但是我使用实现了我所需要的:每个配置使用单独的项目文件

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

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


关于扩展的最初想法,我怀疑扩展的方向是正确的,但不幸的是,我没有尝试它。

可能的方法是,每个配置有一个单独的项目文件;2具有基本配置的扩展项目的核心项目。与你现在试图实现的目标相比,它们更容易管理。有一种观点认为,简单地做ifs是可行的:大多数人都知道它是如何工作的。或者至少比理解MSBuild的人要多得多。我喜欢MSBuild hackery,但我最不想做的事就是花一个小时试图弄清楚为什么这个文件没有被编译,结果却发现项目文件中有魔力。@JasonMalinowski:所讨论的代码是一组分部类,而这些部分位于名为Class.cs、Class.Client.cs和Class.Server.cs的文件中,所以这不太令人困惑。添加所有的ifs是一件乏味的事情——有很多文件要做和维护;2具有基本配置的扩展项目的核心项目。与你现在试图实现的目标相比,它们更容易管理。有一种观点认为,简单地做ifs是可行的:大多数人都知道它是如何工作的。或者至少比理解MSBuild的人要多得多。我喜欢MSBuild hackery,但我最不想做的事就是花一个小时试图弄清楚为什么这个文件没有被编译,结果却发现项目文件中有魔力。@JasonMalinowski:所讨论的代码是一组分部类,而这些部分位于名为Class.cs、Class.Client.cs和Class.Server.cs的文件中,所以这不太令人困惑。添加所有的ifs是一件很乏味的事情,因为有很多文件要做和维护。多亏了这一点,我不知道可以在加载时直接访问项目结构。我暂时放弃了尝试,因为我浪费了太多的时间,需要完成一些实际的工作,但我将在下周某个时候尝试一下这个建议,并汇报进展情况。是的,这是我只有在无法访问或更新ProjectItem或IVsProject.Object中的属性时才能达到的目标之一。不完全理想,但至少所有项目类型的行为都是一致的,而其他两种项目类型的行为并不总是如此。如果你需要更多的帮助,请告诉我。你可以做你想做的事吗?我也有同样的问题。感谢这一点,我不知道加载时可以直接访问项目结构。我暂时放弃了尝试,因为我浪费了太多的时间,需要完成一些实际的工作,但我将在下周某个时候尝试一下这个建议,并汇报进展情况。是的,这是我只有在无法访问或更新ProjectItem或IVsProject.Object中的属性时才能达到的目标之一。不完全理想,但至少所有项目类型的行为都是一致的,而其他两种项目类型的行为并不总是如此。如果你需要更多的帮助,请告诉我。你可以做你想做的事吗?我也有同样的问题。谢谢