How to: Export Settings By Using the Managed Package Framework

The Visual Studio integrated development environment (IDE) uses classes that implement the IProfileManager interface and classes that are registered as supporting a given VSPackage implementation to save the state of a VSPackage.

Because the IDE instantiates the class that implements the IProfileManager interface to support the settings, IProfileManager should be implemented in an independent class.

Note

Do not implement IProfileManager on the class that implements Package.

To implement the export of settings

  1. Declare the class that implements the Visual Studio settings.

    Declare a class as implementing the IProfileManager interface and provide it with a GUID.

    Note

    Classes that implement IProfileManager must also implement IComponent. This can be done by deriving the class from Component.

    For example:

    [Guid("XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX")]
    internal class MyPackageProfileManager : Component, IProfileManager 
    
  2. Ensure that the class that implements the settings obtains correct state information. This procedure is specific to each VSPackage, and may involve obtaining state from automation, querying registry keys, or querying the VSPackage.

    Typically, as in the following example, use the implementation of the LoadSettingsFromStorage method to validate and stage VSPackage state information.

    Note

    The LoadSettingsFromStorage method is also called by the IDE when it initializes the VSPackage that it supports.

    In this case, the implementation of the LoadSettingsFromStorage method does these things:

    • Obtains access to the state information in the VSPackage current configuration and configuration information stored in the registry.

      Dim mySvc As MyPackageService = TryCast(GetService(GetType(IVSMDMyPackage)), MyPackageService) 
      Dim package As Package = TryCast(GetService(GetType(Package)), Package) 
      Dim rootKey As RegistryKey = package.UserRegistryRoot
      
      MyPackageService mySvc = GetService(typeof(IVSMDMyPackage)) as MyPackageService;
      Package package = GetService(typeof(Package)) as Package;
      RegistryKey rootKey = package.UserRegistryRoot;
      
    • Depending on the value returned by the MakeCurrentSettingTheDefault method of the VSPackage, it either updates the registry settings by using the current VSPackage state, or the state by using the registry settings.

      If mySvc.MyPackage.MakeCurrentSettingTheDefault() Then 
          DirectCast(mySvc.MyPackage.packageState, IComPropertyBrowser).SaveState(pbrsKey) 
      Else 
          DirectCast(mySvc.MyPackage.packageState, IComPropertyBrowser).LoadState(pbrsKey) 
      End If
      
      if (mySvc.MyPackage.MakeCurrentSettingTheDefault()){
        ((IComPropertyBrowser)mySvc.MyPackage.packageState).SaveState(pbrsKey);
      }else{
        ((IComPropertyBrowser)mySvc.MyPackage.packageState).LoadState(pbrsKey);
      }
      

      For simplicity in this example, unless the MakeCurrentSettingsTheDefault method returns true, the current state is always reset to the default that is stored in the registry.

  3. Ensure that the class that implements the settings also persists the state to disk.

    The actual writing of state information to the settings disk file must always be performed by the class implementation of the SaveSettingsToXml method. The specifics of a settings writer operation depend on the implementation.

    However, the class must obtain access to state information and must use the supplied IVsSettingsWriter interface to save data to the setting file.

    Typically, as in the following example, the implementation of the SaveSettingsToXml method does not validate state information. The validation is performed in the LoadSettingsFromStorage method. Instead, the implementation merely obtains access to the state information and writes it, in this case, as string data.

    Dim mySvc As MyPackageService = TryCast(GetService(GetType(MyPackage)), MyPackageService) 
    If mySvc IsNot Nothing Then 
        ' Information is stored in a StateObject 
        Dim myState As StateObject = mySvc.MyPackage.packageState 
        writer.WriteSettingString("PbrsAlpha", (If(myState.SortState = SortState.Alphabetical, "1", "0"))) 
        writer.WriteSettingString("PbrsShowDesc", (If(myState.HelpVisible, "1", "0"))) 
    End If
    
    MyPackageService mySvc = GetService(typeof(MyPackage)) as MyPackageService;
    if (mySvc != null) {
      // Information is stored in a StateObject
      StateObject myState = mySvc.MyPackage.packageState;
     writer.WriteSettingString( 
                                "PbrsAlpha", 
                                (myState.SortState == SortState.Alphabetical ? "1" : "0"));
      writer.WriteSettingString( 
                                "PbrsShowDesc", 
                                (myState.HelpVisible ? "1" : "0"));
    }
    

    Implementation details are as follows:

    • In addition to data explicitly written and transparent to the ExportSettings method implementation, the settings API also saves Visual Studio version information. Therefore, saved settings can be compared against the version of the IDE that generated them during settings importation.

    • The value of the pszSettingName argument supplied to a method of the IVsSettingsWriter interface must uniquely identify each data element saved in a settings category.

      Note

      Names must only be unique within the scope of the implementing class. The IDE uses the GUID of the class that implements the settings and the value of pszSettingName to identify each saved setting. If more than one IVsSettingsWriter method that have the same pszSettingName value are called, the original value is overwritten in the settings file.

    • The settings file supports random data access, so the order of read and write operations is not important. In the following example, the order of writer operations in the implementation of the SaveSettingsToXml method is opposite of the read operations in the LoadSettingsFromXml method.

    • If the implementation can map data into one of the four supported formats, then there is no restriction on how much or what type of data can be written.

      Note

      The division of labor between the LoadSettingsFromStorage and SaveSettingsToXml methods depends on the implementation and is somewhat arbitrary. For example, the implementation could be rewritten by using an empty implementation of the LoadSettingsFromStorage method and by having all registry and state queries performed in the SaveSettingsToXml method.

  4. Register the settings implementing class as providing support to a VSPackage.

    Apply an instance of ProvideProfileAttribute that is constructed by using the Type of the class that implements IProfileManager to the VSPackage Package implementation.

    <ProvideProfile(GetType(MyPackageProfileManager), "CoreUI", "MyPackage", 1004, 1004, False)> _ 
    <Guid("YYYYYYYY-YYYY-YYYY-YYYY-YYYYYYYYYYYY")> _ 
    Class MyPackage 
        Inherits Package 
    End Class
    
    [ProvideProfile(typeof(MyPackageProfileManager), "CoreUI", "MyPackage", 1004, 1004, false)]
    [Guid("YYYYYYYY-YYYY-YYYY-YYYY-YYYYYYYYYYYY")]
    class MyPackage: Package 
    

    In this case, the attribute informs the IDE that the MyPackageProfileManager class provides a settings implementation to the MyPackage class. The Custom Settings Point in the registry is created under HKLM\Software\Microsoft\VisualStudio\Version\UserSettings\ CoreUI_MyPackage, where Version is the version of Visual Studio, for example, 10.0.

    For more information, see Persisting Settings and ProvideProfileAttribute.

Example

The following example implements IProfileManager on a class.

Imports System 
Imports System.Runtime.InteropServices 
Imports Microsoft.VisualStudio.Shell 
Imports Microsoft.VisualStudio.Shell.Interop 
Imports Microsoft.Win32 
Imports myPackageNameSpace 
Namespace myProfileManagerNameSpace 
    
    
    <Guid("XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX")> _ 
    Friend Class MyPackageProfileManager 
        Inherits System.ComponentModel.Component 
        Implements IProfileManager 
        Friend Const m_supportVer As Integer = 8 
        Public Sub SaveSettingsToXml(ByVal writer As IVsSettingsWriter) 
            Dim mySvc As MyPackageService = TryCast(GetService(GetType(MyPackage)), MyPackageService) 
            If mySvc IsNot Nothing Then 
                ' Information is stored in a StateObject. 
                Dim myState As StateObject = mySvc.MyPackage.packageState 
                writer.WriteSettingString("PbrsAlpha", (If(myState.SortState = SortState.Alphabetical, "1", "0"))) 
                writer.WriteSettingString("PbrsShowDesc", (If(myState.HelpVisible, "1", "0"))) 
            End If 
        End Sub 
        
        Public Sub LoadSettingsFromXml(ByVal reader As IVsSettingsReader) 
            
            Dim pnMajor As Integer, pnMinor As Integer, pnBuild As Integer 
            ' First, check if data is obtained from the correct major version 
            reader.ReadVersion(pnMajor, pnMinor, pnBuild) 
            If pnMajor <> m_supportVer Then 
                reader.ReportError("Unsupported Version") 
            Else 
                Dim mySvc As MyPackageService = TryCast(GetService(GetType(IVSMDMyPackage)), MyPackageService) 
                If mySvc IsNot Nothing Then 
                    Dim value As String 
                    Dim myState As StateObject = mySvc.MyPackage.packageState 
                    reader.ReadSettingString("PbrsShowDesc", value) 
                    ' Not all values must be present. 
                    If value Is Nothing OrElse value = "" Then 
                        reader.ReportError("Unable to Help Visibility Setting") 
                    Else 
                        myState.HelpVisible = Not value.Equals("0") 
                    End If 
                    reader.ReadSettingString("PbrsAlpha", value) 
                    ' Not all values must be present. 
                    If value Is Nothing OrElse value = "" Then 
                        reader.ReportError("Unable to Retrieve Sort Value") 
                    Else 
                        If Not value.Equals("0") Then 
                            myState.SortState = SortState.Alphabetical 
                        Else 
                            myState.SortState = SortState.Categorized 
                        End If 
                    End If 
                End If 
            End If 
        End Sub 
        
        Public Sub SaveSettingsToStorage() 
            Dim mySvc As MyPackageService = TryCast(GetService(GetType(IVSMDMyPackage)), MyPackageService) 
            Dim package As Package = TryCast(GetService(GetType(Package)), Package) 
            Dim rootKey As RegistryKey = package.UserRegistryRoot 
            
            If mySvc.MyPackage.packageState IsNot Nothing Then 
                Using rootKey 
                    Using pbrsKey As RegistryKey = rootKey.CreateSubKey(Me.[GetType]().Name) 
                        Using pbrsKey 
                            DirectCast(mySvc.MyPackage.packageState, IComPropertyBrowser).SaveState(pbrsKey) 
                        End Using 
                    End Using 
                End Using 
            End If 
        End Sub 
        
        Public Sub LoadSettingsFromStorage() 
            Dim mySvc As MyPackageService = TryCast(GetService(GetType(IVSMDMyPackage)), MyPackageService) 
            Dim package As Package = TryCast(GetService(GetType(Package)), Package) 
            Dim rootKey As RegistryKey = package.UserRegistryRoot 
            Using rootKey 
                Dim pbrsKey As RegistryKey = rootKey.OpenSubKey(Me.[GetType]().Name) 
                If pbrsKey IsNot Nothing Then 
                    Using pbrsKey 
                        If mySvc.MyPackage.MakeCurrentSettingTheDefault() Then 
                            DirectCast(mySvc.MyPackage.packageState, IComPropertyBrowser).SaveState(pbrsKey) 
                        Else 
                            DirectCast(mySvc.MyPackage.packageState, IComPropertyBrowser).LoadState(pbrsKey) 
                        End If 
                    End Using 
                End If 
            End Using 
        End Sub 
    End Class 
End Namespace 

Convert C# to VB.NET
namespace myProfileManagerNameSpace  {
  
  using System;
  using System.Runtime.InteropServices;
  using Microsoft.VisualStudio.Shell;
  using Microsoft.VisualStudio.Shell.Interop;
  using Microsoft.Win32;
  using myPackageNameSpace;
  
  
  [Guid("XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX")]
  internal class MyPackageProfileManager : System.ComponentModel.Component , IProfileManager {
    internal const int m_supportVer = 8;
    public void SaveSettingsToXml(IVsSettingsWriter writer) {
      MyPackageService mySvc = GetService(typeof(MyPackage)) as MyPackageService;
      if (mySvc != null) {
        // Information is stored in a StateObject.
        StateObject myState = mySvc.MyPackage.packageState;
        writer.WriteSettingString( 
                                  "PbrsAlpha", 
                                  (myState.SortState == SortState.Alphabetical ? "1" : "0"));
        writer.WriteSettingString( 
                                  "PbrsShowDesc", 
                                  (myState.HelpVisible ? "1" : "0"));
      }
    }
    
    public void LoadSettingsFromXml(IVsSettingsReader reader)
    {
      
      int pnMajor, pnMinor, pnBuild;
      // First, check if data is obtained from the correct major version 
      reader.ReadVersion(pnMajor, pnMinor, pnBuild);
      if (pnMajor != m_supportVer){
        reader.ReportError("Unsupported Version");
      }else{
        MyPackageService mySvc = GetService(typeof(IVSMDMyPackage)) as MyPackageService;
        if (mySvc != null){
          string value;
          StateObject myState = mySvc.MyPackage.packageState;
          reader.ReadSettingString("PbrsShowDesc", out value);
          // Not all values must be present.
          if (value == null || value == ""){
              reader.ReportError("Unable to Help Visibility Setting");
          }else{
            myState.HelpVisible = !value.Equals("0");
          }
          reader.ReadSettingString("PbrsAlpha", out value);
          // Not all values must be present.
          if (value == null || value == ""){
              reader.ReportError("Unable to Retrieve Sort Value");
          }else{
            if (!value.Equals("0")){
              myState.SortState = SortState.Alphabetical;
            }else{
              myState.SortState = SortState.Categorized;
            }
          }
        }
      }
    }

    public void SaveSettingsToStorage() {
      MyPackageService mySvc = GetService(typeof(IVSMDMyPackage)) as MyPackageService;
      Package package = GetService(typeof(Package)) as Package;
      RegistryKey rootKey = package.UserRegistryRoot;
      
      if (mySvc.MyPackage.packageState != null) {
        using (rootKey) {
          using(RegistryKey pbrsKey = rootKey.CreateSubKey(this.GetType().Name)) {
            using (pbrsKey) {
              ((IComPropertyBrowser)mySvc.MyPackage.packageState).SaveState(pbrsKey);
            }
          }
        }
      }
    }
    
    public void LoadSettingsFromStorage() {
      MyPackageService mySvc = GetService(typeof(IVSMDMyPackage)) as MyPackageService;
      Package package = GetService(typeof(Package)) as Package;
      RegistryKey rootKey = package.UserRegistryRoot;
      using (rootKey) {
        RegistryKey pbrsKey = rootKey.OpenSubKey(this.GetType().Name);
        if (pbrsKey != null) {
          using (pbrsKey) {
            if (mySvc.MyPackage.MakeCurrentSettingTheDefault()){
              ((IComPropertyBrowser)mySvc.MyPackage.packageState).SaveState(pbrsKey);
            }else{
              ((IComPropertyBrowser)mySvc.MyPackage.packageState).LoadState(pbrsKey);
            }
          }
        }
      }
    }
  }
}

See Also

Tasks

How to: Import Settings By Using the Managed Package Framework

Reference

IProfileManager

IVsSettingsWriter

Concepts

Persisting Settings