【问题标题】:Modifying Visual Studio project properties programatically without modifying actual project files以编程方式修改 Visual Studio 项目属性而不修改实际项目文件
【发布时间】:2019-07-19 15:48:04
【问题描述】:

我正在寻找一种方法来防止 Visual Studio 将项目属性更改反映到 *.csproj 文件中。我只想为单个构建操作设置属性,然后它们应该被丢弃。

我在我的 Visual Studio 插件中使用 EnvDTE 自动化对象。下面是我的示例代码,它将"UseHostCompilerIfAvailable" 属性设置(或更改)为"false",用于即将构建的项目的特定配置和平台。从 Visual Studio UI 启动构建。

在构建初始化过程中的某处,Visual Studio 将所有项目属性更改写入项目文件,这是我试图阻止的。

dte.Events.BuildEvents.OnBuildProjConfigBegin += BuildEvents_OnBuildProjConfigBegin;
...
private void BuildEvents_OnBuildProjConfigBegin(string Project, string ProjectConfig, string Platform, string SolutionConfig)
{
    ThreadHelper.ThrowIfNotOnUIThread();
    IVsSolution solution = (IVsSolution)this.GetService(typeof(SVsSolution));
    solution.GetProjectOfUniqueName(Project, out IVsHierarchy hier);
    IVsBuildPropertyStorage storage = hier as IVsBuildPropertyStorage;
    storage.SetPropertyValue("UseHostCompilerIfAvailable", $"{ProjectConfig}|{Platform}", (uint)Microsoft.VisualStudio.Shell.Interop._PersistStorageType.PST_PROJECT_FILE, "false");
}

我知道我可以保存属性更改并在构建完成后恢复它们,或者我可以缓存项目文件并最终回滚它们,但这些方法可能会产生不良副作用。我什至会很高兴能得到一些我应该朝哪个方向看的想法。

【问题讨论】:

    标签: c# visual-studio msbuild envdte


    【解决方案1】:

    为什么必须以编程方式进行?或许你可以试试Directory.build.props文件。

    将它放在解决方案文件夹中以自定义您的构建,而无需修改项目文件。

    【讨论】:

    • 感谢您的建议,我其实已经考虑过Directory.Build.props,但用户可能已经有了它。我正在开发插件,这个插件不允许以任何方式改变解决方案的结构,它的所有操作就像它不存在一样。关闭后,一切都应保持原样。
    【解决方案2】:

    从您的问题来看,在我看来,您必须处理 VS 默认插件 SDK 方法未涵盖的问题。

    在这种情况下,您可以考虑尝试在 VS 中挂钩 NtCreateProcess 以获得您需要创建的 MSBuild。

    NtCreateProcess 允许设置挂起标志。然后在挂起状态下创建 MSBuild。这一刻允许您对该过程进行更改。如果您有自定义加载程序,请考虑在挂钩中使用它,而不是调用本机 NtCreateProcess。

    在注入的库内部做钩子来访问你需要的属性。理想情况下,这些应该只是一些注册表项。但如果它在 FS 文件中的 XML 中,那么它可能是用于访问 XML 属性的其他一些高级 API。

    您感兴趣的 MSBuild 进程中的 NtCreateProcess 也需要以相同的方式挂钩,以将此逻辑传递给所有子进程,以使这个解决方案更加健壮。

    【讨论】:

    • 感谢您的建议。实际上,我还尝试使用托管挂钩,因为 MSBuild 是使用 C# 开发的。整个构建系统非常脆弱和复杂,我希望能得到一些新的想法和简单的解决方案。不幸的是,看起来钩子是要走的路。
    【解决方案3】:

    作为Directory.Build.props 的替代方案,您是否考虑将ImportBefore/ImportAfter 目标文件放到MSBuildUserExtensionsPath 指向的目录中?该目录中的所有文件都将自动包含在构建中。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-02-01
      • 1970-01-01
      • 2012-05-29
      • 1970-01-01
      相关资源
      最近更新 更多