培训
在项目文件中保存数据
项目子类型可以在项目文件中保存和检索特定于子类型的数据。 托管包框架(MPF)提供两个接口来完成此任务:
该 IVsBuildPropertyStorage 接口允许从 项目文件的 MSBuild 节访问属性值。 每当用户需要加载或保存生成相关数据时,任何用户都可以调用提供 IVsBuildPropertyStorage 的方法。
用于 IPersistXMLFragment 在自由格式 XML 中保留非生成相关数据。 每当 Visual Studio 需要在项目文件中保存非生成相关数据时,Visual Studio 都调用由 Visual Studio 提供 IPersistXMLFragment 的方法。
有关如何持久保存生成和非生成相关数据的详细信息,请参阅 MSBuild 项目文件中的持久化数据。
SetPropertyValue调用该方法以保存项目文件的完整路径。
private SpecializedProject project; IVsBuildPropertyStorage projectStorage = (IVsBuildPropertyStorage)project; string newFullPath = GetNewFullPath(); // Set a full path of the project file. ErrorHandler.ThrowOnFailure(projectStorage.SetPropertyValue( "MSBuildProjectDirectory", String.Empty, (uint)_PersistStorageType.PST_PROJECT_FILE, newFullPath));
GetPropertyValue调用该方法以检索项目文件的完整路径。
private SpecializedProject project; IVsBuildPropertyStorage projectStorage = (IVsBuildPropertyStorage)project; string fullPath; // Get a full path of the project file. ErrorHandler.ThrowOnFailure(projectStorage.GetPropertyValue( "MSBuildProjectDirectory", String.Empty, (uint)_PersistStorageType.PST_PROJECT_FILE, out fullPath));
实现该方法 IsFragmentDirty 以确定 XML 片段自上次保存到其当前文件后是否发生了更改。
public int IsFragmentDirty(uint storage, out int pfDirty) { pfDirty = 0; switch (storage) { case (uint)_PersistStorageType.PST_PROJECT_FILE: { if (isDirty) pfDirty |= 1; break; } case (uint)_PersistStorageType.PST_USER_FILE: { // We do not store anything in the user file. break; } } // Forward the call to inner flavor(s) if (pfDirty == 0 && innerCfg != null && this.innerCfg is IPersistXMLFragment) return ((IPersistXMLFragment)this.innerCfg).IsFragmentDirty(storage, out pfDirty); return VSConstants.S_OK; }
Save实现在项目文件中保存 XML 数据的方法。
public int Save(ref Guid guidFlavor, uint storage, out string pbstrXMLFragment, int fClearDirty) { pbstrXMLFragment = null; if (IsMyFlavorGuid(ref guidFlavor)) { switch (storage) { case (uint)_PersistStorageType.PST_PROJECT_FILE: { // Create XML for our data. XmlDocument doc = new XmlDocument(); XmlNode root = doc.CreateElement(this.GetType().Name); XmlNode node = doc.CreateElement(targetsTag); node.AppendChild(doc.CreateTextNode(this.TargetsToExecute)); root.AppendChild(node); node = doc.CreateElement(updateTargetsTag); node.AppendChild(doc.CreateTextNode(this.UpdateTargetList.ToString())); root.AppendChild(node); doc.AppendChild(root); // Get XML fragment representing our data pbstrXMLFragment = doc.InnerXml; if (fClearDirty != 0) isDirty = false; break; } case (uint)_PersistStorageType.PST_USER_FILE: { // We do not store anything in the user file. break; } } } // Forward the call to inner flavor(s) if (this.innerCfg != null && this.innerCfg is IPersistXMLFragment) return ((IPersistXMLFragment)this.innerCfg).Save(ref guidFlavor, storage, out pbstrXMLFragment, fClearDirty); return VSConstants.S_OK; }
InitNew实现初始化项目扩展属性和其他独立于生成的数据的方法。 如果项目文件中不存在 XML 配置数据,则调用此方法。
public int InitNew(ref Guid guidFlavor, uint storage) { //Return,if it is our guid. if (IsMyFlavorGuid(ref guidFlavor)) return VSConstants.S_OK; //Forward the call to inner flavor(s). if (this.innerCfg != null && this.innerCfg is IPersistXMLFragment) return ((IPersistXMLFragment)this.innerCfg).InitNew(ref guidFlavor, storage); return VSConstants.S_OK;
Load实现从项目文件加载 XML 数据的方法。
public int Load(ref Guid guidFlavor, uint storage, string pszXMLFragment) { if (IsMyFlavorGuid(ref guidFlavor)) { switch (storage) { case (uint)_PersistStorageType.PST_PROJECT_FILE: { // Load our data from the XML fragment. XmlDocument doc = new XmlDocument(); XmlNode node = doc.CreateElement(this.GetType().Name); node.InnerXml = pszXMLFragment; if (node == null || node.FirstChild == null || node.FirstChild.ChildNodes.Count == 0 || node.FirstChild.ChildNodes[0].Name != targetsTag) break; this.TargetsToExecute = node.FirstChild.ChildNodes[0].InnerText; if (node.FirstChild.ChildNodes.Count <= 1 || node.FirstChild.ChildNodes[1].Name != updateTargetsTag) break; this.UpdateTargetList = bool.Parse(node.FirstChild.ChildNodes[1].InnerText); break; } case (uint)_PersistStorageType.PST_USER_FILE: { // We do not store anything in the user file. break; } } } // Forward the call to inner flavor(s) if (this.innerCfg != null && this.innerCfg is IPersistXMLFragment) return ((IPersistXMLFragment)this.innerCfg).Load(ref guidFlavor, storage, pszXMLFragment); return VSConstants.S_OK; }
备注
本主题中提供的所有代码示例都是 VSSDK 示例中较大示例的一部分。
其他资源
文档
-
在属性窗口中公开属性 - Visual Studio (Windows)
浏览对象的公共属性,以及如何在属性窗口中反映对这些属性所做的更改。
-
创建基本项目系统,第 1 部分 - Visual Studio (Windows)
在 Visual Studio 中创建一个基本项目,用于保存和组织源代码文件和其他资产,以及处理项目模板和实例。
-
将搜索添加到工具窗口 - Visual Studio (Windows)
将搜索功能(包括搜索框、筛选和进度指示器)添加到 Visual Studio 中的工具窗口。
-
动态添加菜单项 - Visual Studio (Windows)
了解如何使用 DynamicItemStart 命令标志在运行时添加菜单项。 本文介绍如何在 Visual Studio 解决方案中设置启动项目。