c# - 如何以分层方式保存 Visual Studio 项目扩展属性

标签 c# xml visual-studio msbuild vsix

我将如何在 Visual Studio 2015 项目文件中动态创建/修改/删除扩展属性,以便 XML 维护以下结构:

<ProjectExtensions>
    <VisualStudio>
        <MyProject>
            <MyProjectProperty1>3</MyProjectProperty>
            <MyProjectProperty2>8</MyProjectProperty>
            <MyProjectProperty3>2016</MyProjectProperty>
        </MyProject>
    </VisualStudio>
</ProjectExtensions>

我已经知道如何使用 EnvDTE.Globals 创建它的变体,然后使用类似于以下的代码保留值并选择性地保存项目:

EnvDTE.Project oProject = dte.Solution.Projects.Item(1);
Globals oGlobals = oProject.Globals;
oGlobals["MyProjectProperty1"] = "3";

这里的问题是这段代码会产生:

<ProjectExtensions>
  <VisualStudio>
    <UserProperties MyProjectProperties1="3" MyProjectProperties2="8" MyProjectProperties3="2016" />
  </VisualStudio>
</ProjectExtensions>

我想过使用 IPersistXMLFragmentIVsProjectFlavorCfg 组合,但这种方法缺少从项目文件中读取、写入和删除 XML 代码的关键概念。 IPersistXMLFragment 加载方法将 XML 代码作为字符串,将值加载到字典中,然后管理这些值。 save 方法执行相反的操作,从管理构造返回到基于字符串的 XML 版本。正如我刚才所说,缺少的是从实际项目文件中读取、写入和删除,而无需手动编辑文件并导致项目重新加载。

我还玩过 IVsHierarchyMSBuild VSIX 接口(interface)/对象,但没走多远。

有没有人有什么想法?

最佳答案

您可以使用 IVsBuildPropertyStorage .作为输入,我使用 EnvDTE.Project对象。
SetCsprojProperty将属性设置在第一个 <PropertyGroup>如果 csproj 文件不存在:

private IVsHierarchy GetIVsHierarchyObject(Project project)
{
  string uniqueName = project?.UniqueName;
  int ret = Solution.GetProjectOfUniqueName(uniqueName, out IVsHierarchy hierarchyProject);
  if (ret != VSConstants.S_OK) return null;

  return hierarchyProject;
}

public string GetCsprojProperty(Project project, string name)
{
  IVsHierarchy hierarchyProject = GetIVsHierarchyObject(project);
  if (hierarchyProject is IVsBuildPropertyStorage buildPropertyStorage)
  {
    var result = buildPropertyStorage.GetPropertyValue(name, "", (uint)_PersistStorageType.PST_PROJECT_FILE, out string value);
    if (result == VSConstants.S_OK)
    {
      return value;
    }
  }

  return null;
}

public bool SetCsprojProperty(Project project, string name, string value)
{
  IVsHierarchy hierarchyProject = GetIVsHierarchyObject(project);
  if (hierarchyProject is IVsBuildPropertyStorage buildPropertyStorage)
  {
    var result = buildPropertyStorage.SetPropertyValue(name, "", (uint)_PersistStorageType.PST_PROJECT_FILE, value);
    if (result == VSConstants.S_OK)
    {
      return true;
    }
  }

  return false;
}

关于c# - 如何以分层方式保存 Visual Studio 项目扩展属性,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35871424/

相关文章:

c# - 在可移植类库中包含 XPathSelectElement

java - 如何在 XSD 中指定重复元素

visual-studio - 在 Visual Studio 调试器中显示二维数组

c# - 为什么 C# 没有为变量和方法设计 'const'?

c# - 计时器与重复性后台 worker

c# - 如何从 Exchange Server 2007 SP1 获取最新的 SyncState

java Spring 。棘手的 json 和 xml 序列化注释

C# 在应用程序之间共享实例

c++ - Visual Studio 可维护性索引的层次结构仅向下到 main()

javascript - knockout : How to apply multiple partial view models to the same element