| title | Saving Data in Project Files | |||
|---|---|---|---|---|
| description | Learn about the interfaces that the Managed Package Framework provides to save and retrieve subtype-specific data in the project file. | |||
| ms.date | 11/04/2016 | |||
| ms.topic | how-to | |||
| helpviewer_keywords |
|
|||
| author | tinaschrepfer | |||
| ms.author | tinali | |||
| ms.subservice | extensibility-integration |
A project subtype can save and retrieve subtype-specific data in the project file. The Managed Package Framework (MPF) provides two interfaces to accomplish this task:
-
The xref:Microsoft.VisualStudio.Shell.Interop.IVsBuildPropertyStorage interface allows to access property values from the MSBuild section of the project file. The methods provided by xref:Microsoft.VisualStudio.Shell.Interop.IVsBuildPropertyStorage can be called by any user whenever the user needs to load or save build related data.
-
The xref:Microsoft.VisualStudio.Shell.Interop.IPersistXMLFragment is used to persist non-build related data in free-form XML. The methods provided by xref:Microsoft.VisualStudio.Shell.Interop.IPersistXMLFragment are called by Visual Studio whenever Visual Studio needs to persist non-build related data in the project file.
For more information on how to persist build and non-build related data, see Persist data in the MSBuild project file.
-
Call the xref:Microsoft.VisualStudio.Shell.Interop.IVsBuildPropertyStorage.SetPropertyValue%2A method to save a full path of the project file.
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));
-
Call the xref:Microsoft.VisualStudio.Shell.Interop.IVsBuildPropertyStorage.GetPropertyValue%2A method to retrieve a full path of the project file.
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));
-
Implement the xref:Microsoft.VisualStudio.Shell.Interop.IPersistXMLFragment.IsFragmentDirty%2A method to determine whether an XML fragment has changed since it was last saved to its current file.
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; } -
Implement the xref:Microsoft.VisualStudio.Shell.Interop.IPersistXMLFragment.Save%2A method to save the XML data in the project file.
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; }
-
Implement the xref:Microsoft.VisualStudio.Shell.Interop.IPersistXMLFragment.InitNew%2A method to initialize the project extension properties and other build-independent data. This method is called if there is no XML configuration data present in the project file.
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; -
Implement the xref:Microsoft.VisualStudio.Shell.Interop.IPersistXMLFragment.Load%2A method to load the XML data from the project file.
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; }
Note
All code examples provided in this topic are parts of a larger example in VSSDK samples.