项目子类型可以保存和检索在项目文件中特定于子类型的数据。 托管包框架 (MPF)提供两个接口完成此任务:
IVsBuildPropertyStorage 接口允许访问从项目文件的 MSBuild 部分的属性值。 IVsBuildPropertyStorage 提供的方法可由所有用户调用,只要用户需要加载或保存生成相关的数据。
IPersistXMLFragment 在任意形式的 XML 用于保留非编译相关的数据。 IPersistXMLFragment 提供的方法。 Visual Studio 调用,只要 Visual Studio 需要保留非编译相关在项目文件中的数据。
有关如何保持的更多信息生成和非编译相关的数据,请参见 在 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; }
备注
本主题提供的所有代码示例摘自一个更大的示例的一部分, Visual Studio 扩展性示例。