我正在寻找一种方法,以防止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");
}
我知道我可以保存属性更改并在构建完成后还原它们,也可以缓存项目文件并最终将它们回滚,但是这些方法可能会产生不良影响。我什至很高兴得到一些想法,我应该朝哪个方向看。
答案 0 :(得分:1)
为什么必须以编程方式进行操作?也许您可以尝试Directory.build.props文件。
将其放在解决方案文件夹中以自定义构建,而无需修改项目文件。
答案 1 :(得分:0)
从您的问题看来,您似乎必须处理VS默认插件SDK方法未涵盖的问题。
在这种情况下,您可以考虑尝试在VS中挂接NtCreateProcess,以获取需要创建的MSBuild时刻。
NtCreateProcess允许设置暂停标志。然后以暂停状态创建MSBuild。此刻,您可以对该过程进行更改。如果您有自定义加载器,请考虑在挂钩中使用它,而不是调用本机NtCreateProcess。
在注入的库内部做钩子以访问所需的属性。理想情况下,这些应该只是一些注册表项。但是,如果它在FS文件中的XML内,则它可能是用于访问XML属性的其他一些高级API。
您感兴趣的MSBuild进程内部的NtCreateProcess也需要以相同的方式进行挂钩,以将此逻辑传递给所有子进程,以使该解决方案更可靠。
答案 2 :(得分:0)
作为Directory.Build.props
的替代方法,您是否考虑过将ImportBefore/ImportAfter
目标文件拖放到MSBuildUserExtensionsPath指向的目录中?该目录中的所有文件将自动包含在构建中。