Skip to content

Latest commit

 

History

History
206 lines (166 loc) · 8.35 KB

File metadata and controls

206 lines (166 loc) · 8.35 KB
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
data [Visual Studio], saving in project files
project files
project files, saving data
author tinaschrepfer
ms.author tinali
ms.subservice extensibility-integration

Save data in project files

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.

Save and retrieve build related data

To save a build related data in the 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));
    

To retrieve build related data from the project file

  • 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));
    

Save and retrieve non-build related data

To save non-build related data in the project file

  1. 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;
    
    }
    
  2. 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;
    }
    

To retrieve non-build related data in the project file

  1. 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;
    
  2. 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.

Related content