在项目文件中保存数据
项目子类型可以在项目文件中保存和检索特定于子类型的数据。 托管包框架(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 示例中较大示例的一部分。