Freigeben über


Gewusst wie: Verwendungs-Interopassemblys, um Einstellungen zu importieren

VSPackage können importiert Visual Studio Einstellungen von der integrierten Entwicklungsumgebung (IDE). Die IDE verwendet eine VSPackages Implementierung der IVsUserSettings-Schnittstelle, um zu bestimmen, wie die VSPackages Konfiguration abgerufen werden soll.

Hinweis

Das verwaltete Paketframework (MPF) stellt einen Satz verwalteter Klassen aufgerufen, um die Erstellung von Visual Studio-Erweiterungen zu erleichtern.Um diese Aufgabe mithilfe des MPF finden Sie unter Gewusst wie: Import-Einstellungen mithilfe von verwaltetem Paketframeworks.

Um Einstellungen in einem VSPackage implementieren import

  1. Implementieren Sie grundlegende Unterstützung für den Visual Studio Mechanismus zur Einstellungen.

    • Registrieren von VSPackages Mechanismus für die Einstellungen des unterstützt, indem Sie eine oder mehrere benutzerdefinierte Einstellungs-Punkte definieren.

      Weitere Informationen finden Sie unter Beibehalten von Einstellungen.

    • Deklarieren Sie, dass ein VSPackage die IVsUserSettings-Schnittstelle implementiert, z. B.:

      public class MyPackage : IVsPackage, IVsUserSettings, IVsUserSettingsQuery
      
    • Stellen Sie sicher, dass die VSPackages Implementierung des QueryInterface-Methode stellt eine IVsUserSettings-Schnittstelle, wenn Sie mit IID_IVsUserSettingsaufgerufen werden. Beispiele:

      STDMETHODIMP MyPackage::QueryInterface(THIS_ REFIID riid, LPVOID FAR* ppvObj)
      {
          if (ppvObj == NULL)
              return E_POINTER;
      
          *ppvObj = NULL;
      
          if (riid == IID_IUnknown)
              *ppvObj = (LPVOID)(IUnknown *)(IClassFactory*)this;
          else if (riid == IID_IClassFactory)
              *ppvObj = (LPVOID)(IClassFactory *)this;
          else if (riid == IID_IVsPackage)
              *ppvObj = (LPVOID)(IVsPackage *)this;
          else if (riid == IID_IVsPersistSolutionOpts)
              *ppvObj = (LPVOID)(IVsPersistSolutionOpts *)this;
          else if (riid == IID_IVsPersistSolutionProps)
              *ppvObj = (LPVOID)(IVsPersistSolutionProps *)this;
          else if (riid == IID_IVsComponentSelectorProvider)
              *ppvObj = (LPVOID)(IVsComponentSelectorProvider *)this;
          else if (riid == IID_IVsUserSettings)
              *ppvObj = (LPVOID)(IVsUserSettings *)this;
          else if (riid == IID_IVsUserSettingsQuery)
              *ppvObj = (LPVOID)(IVsUserSettingsQuery *)this;
      
          if (*ppvObj)
          {
              AddRef();
              return NOERROR;
          }
          return E_NOINTERFACE;
      }
      
  2. Abrufen von Informationen über Einstellungen ab oder legt diese fest.

    Zum Abrufen von Informationen über Einstellungen zu unterstützen, muss ein VSPackage die ImportSettings-Methode implementieren.

    Um Daten zu lesen, muss eine VSPackages Implementierung der Schnittstelle IVsUserSettings die ersten beiden Argumente verwenden, die durch die IDE übergeben werden: Die GUID der dieser benutzerdefinierten Kategorie des Einstellungs-Punkts und eine IVsSettingsReader-Schnittstelle.

    1. Eine VSPackages Implementierung der ImportSettings-Methode muss die Kategorie GUID überprüfen, die übergeben wird und den richtigen Mechanismus für den abrufenden Bedingung auswählen.

      Im nachfolgenden Beispiel wird die ImportSettings-Methode ruft eine andere Implementierung zum Abrufen des zustandes Befehlsleiste im Gegensatz zum Abrufen des Tastenzuordnungs zustandes.

    2. VSPackage muss die angegebene IVsSettingsReader-Schnittstelle verwenden, um Daten an die Einstellungsdatei abzurufen.

      Hinweis

      Wenn die Informationen zum Festlegen einer Funktion als Visual Studio-Version ändern, muss eine VSPackages Implementierung der ImportSettings-Methode die ReadFileVersion-Methode vor dem Lesen von Daten verwenden, um die IDE-Version zu überprüfen.

      Die Schnittstelle stellt Methoden für das Lesen von unterschiedlichen Datentypen in der Einstellungsdatei bereit.

      interface IVsSettingsReader : IUnknown

      {

          HRESULT ReadSettingString(WCHAR *pszSettingName, BSTR *pbstrSettingValue);

          HRESULT ReadSettingLong(WCHAR *pszSettingName, long *plSettingValue);

          HRESULT ReadSettingBoolean(WCHAR *pszSettingName, BOOL *pfSettingValue);

          HRESULT ReadSettingAttribute(LPCOLESTR pszSettingName,LPCOLESTR pszAttributeName, BSTR *pbstrSettingValue); //Internal use only

          HRESULT ReadSettingBytes(WCHAR *pszSettingName, BYTE *pSettingValue, long *plDataLength, long lDataMax);

          HRESULT ReadVersion(int *pnMajor, int *pnMinor, int *pnBuild);

          HRESULT ReportError(WCHAR *pszError);

      };

    Die Einstellungsdatei unterstützt zufälligen Datenzugriff, sodass die Reihenfolge des Lese- und Schreibvorgänge Einstellungen, die Operationen nicht wichtig ist.

    Dies wird im exportierenden und importierenden Befehlsleiste - Zustand (ExportSettings_CommandBar und ImportSettings_CommandBar) der Implementierung im folgenden Beispiel veranschaulicht.

  3. Validate abgerufene Daten ab.

    Die Einstellungen sind in XML-Dateien enthalten Informationen, die manuell bearbeitet werden können.

SicherheitshinweisSicherheitshinweis

Die Informationen über die Einstellungen auf dem Datenträger möglicherweise beschädigt werden, enthalten möglicherweise versionsspezifische Einstellungen und können als Fahrzeug für böswilligen Angriff verwendet werden.Die Gültigkeit eines Datenelements, das von der IVsSettingsReader-Methode zurückgegeben wird, sollte überprüft werden.

  • Zur Unterstützung der Version von Visual Studio zu überprüfende der abgerufenen Einstellungen für die zu erstellende die ReadFileVersion-Methode aufrufen, um die Version abzurufen.

  • So bewirken, dass die IDE einen Benutzer zu benachrichtigen, dass ein importiertes Datenelement nicht überprüft, VSPackage-Aufrufe die ReportError-Methode.

  1. Anwenden von Informationen über Einstellungen.

    1. Die Implementierung der ImportSettings-Methode muss den Wert des dritten Arguments berücksichtigen, das die IDE darauf erfolgreich war. Die unterstützten Werte sind Member der __UserSettingsFlags-Enumeration. Weitere Informationen finden Sie unter __UserSettingsFlags.

      Im folgenden Beispiel wird die Implementierung für das Importieren von Einstellungen der Befehlsleiste (ImportSettings_Commandbar) den Wert dieses Arguments bestimmt, ob Einstellungen, um vorhandene Werte zu überschreiben sie anwendet oder additiv zu aktualisieren.

    2. Sie müssen eine Write-through cache methodik implementieren, wenn Sie importierte Einstellungen anwenden.

      Zustandsinformationen in der Registrierung oder im Dateisystem müssen aktualisiert werden, gleichzeitig wie Einstellungen in der IDE angewendet werden. Dadurch wird sichergestellt kohärenz Konfiguration und unterstützt Mehrfachinstanze IDE-Szenarien.

  2. Wachsames IDE, wie Einstellungen import behandelt.

    Verwenden Sie das zurückgegebene pfRestartRequired-Argument der ImportSettings-Methode, um die IDE anzumelden, wenn ein Neustart erforderlich ist, um die importierten Einstellungen anzuwenden.

    Wenn die VSPackages Implementierung der ImportSettings-Methode truezurückgibt, wird der Benutzer aufgefordert, die IDE neu zu starten.

Beispiel

Dieses Beispiel zeigt, wie Sie Einstellungsdaten importiert und exportiert.

static const WCHAR c_szFirstSettingName[] = L"FirstSettingName";
static const WCHAR c_szRandomTrashBytes[] = L"RandomTrashBytes";
static const WCHAR c_szRandomTrashLength[] = L"RandomTrashLength";
static const WCHAR c_szBreakPointWindow[] = L"Breakpoints Window";
// --------------------------------------------------------------------------
//    IVsUserSettings methods used for configuration export and import
//    Delegate to the right shell object based on the category GUID
// --------------------------------------------------------------------------
static const WCHAR c_szFirstSettingName[] = L"FirstSettingName";
static const WCHAR c_szRandomTrashBytes[] = L"RandomTrashBytes";
static const WCHAR c_szRandomTrashLength[] = L"RandomTrashLength";
static const WCHAR c_szBreakPointWindow[] = L"Breakpoints Window";

// Export Settings.

STDMETHOD(NeedExport)(WCHAR* pszCategoryGUID, BOOL *pfNeedExport)
{
    if (!pfNeedExport)
        return E_INVALIDARG;
    
    CLSID clsidCategory;
    HRESULT hr= S_OK;
    
    hr = CLSIDFromString(pszCategoryGUID, &clsidCategory);
    IfFailGo(hr);
    if (GUID_Profiles_CommandBars == clsidCategory) {
        *pfNeedExport = TRUE; //Always export Command Bar Configuration
    }else if (GUID_Profiles_KeyBindings == clsidCategory) {
        *pfNeedExport = FALSE; //By Default don't export key bindings
        if (m_fMake_Permanent)
            *pfNeedExport = TRUE; //Export if user wants current configuration saved.
    }else{
        hr = E_UNEXPECTED;
    }
 Error:
    return hr;
}

STDMETHOD(ExportSettings)(WCHAR *pszCategoryGUID, IVsSettingsWriter *pSettings)
{
    CLSID clsidCategory;
    HRESULT hr;
    hr = CLSIDFromString(pszCategoryGUID, &clsidCategory);
    IfFailGo(hr);
    // Delegate to the right internal implementation based on the requested category.
    
    if (GUID_Profiles_CommandBars == clsidCategory) {
        hr = ExportSettings_CommandBars(pSettings);
    }else if (GUID_Profiles_KeyBindings == clsidCategory) {
        hr = ExportSettings_KeyBindings(pSettings);
    }else{
        hr = E_UNEXPECTED;
    }
 Error:
    return hr;
};


HRESULT ExportSettings_CommandBars(IVsSettingsWriter *pSettings)
{
    if (!pSettings)
        return E_INVALIDARG;
    
    hr = pSettings->WriteSettingString(c_szFirstSettingName, L"Value1");
    IfFailGo(hr);
    
    int cRandomTrash = 12345;
    BYTE *pRandomTrash = (BYTE *)VSAlloc(cRandomTrash);
    if (pRandomTrash){
        hr = pSettings->WriteSettingBytes(c_szRandomTrashBytes, pRandomTrash, cRandomTrash);
        IfFailGo(hr);
        hr = pSettings->WriteSettingLong(c_szRandomTrashLength, cRandomTrash);
        IfFailGo(hr);
    }
    
 Error:
    return hr;
};

HRESULT ExportSettings_KeyBindings(IVsSettingsWriter *pSettings)
{
    if (!pSettings)
        return E_INVALIDARG;
    
    hr = pSettings->WriteSettingString(c_szBreakPointWindow, L"Ctrl + Alt + B");
    IfFailGo(hr);
    
 Error:
    return hr;
};

STDMETHOD(ImportSettings)(WCHAR *pszCategoryGUID, IVsSettingsReader *pSettings, UserSettingsFlags flags, BOOL *pfRestartRequired)
{
    CLSID clsidCategory;
    HRESULT hr;
    
    hr = CLSIDFromString(pszCategoryGUID, &clsidCategory);
    IfFailGo(hr);
    
    // Delegate to the right internal implementation based on the requested category.
    if (GUID_Profiles_CommandBars == clsidCategory)
        {
            hr = ImportSettings_CommandBars(, pSettings, flags, pfRestartRequired);
        }
    else if (GUID_Profiles_KeyBindings == clsidCategory)
        {
            hr = ImportSettings_KeyBindings( pSettings, flags, pfRestartRequired);
        }
    else
        {
            hr = E_UNEXPECTED;
        }
    
 Error:
    return hr;
};

// Import Settings.

HRESULT ImportSettings_CommandBars(IVsSettingsReader *pSettings, UserSettingsFlags flags, BOOL *pfRestartRequired)
{
    if (!pSettings)
        return E_INVALIDARG;
    
    if (pfRestartRequired)
        {
            *pfRestartRequired = FALSE; //Nobody should require a restart!!
        }
    
    CComBSTR bstrFirstSettingName;
    long lTrashLength = 0;
    BYTE *pTrashBytes = NULL;
    
    // Determines whether to import as an additive operation, or a reset all settings operation.
    BOOL fResetCompletely = FALSE; 
    
    if (flags & USF_ResetOnImport)
        fResetCompletely = TRUE;
    
    hr = pSettings->ReadSettingString(c_szFirstSettingName, &bstrFirstSettingName);
    IfFailGo(hr);
    
    hr = pSettings->ReadSettingLong(c_szRandomTrashLength, &lTrashLength);
    IfFailGo(hr);
    
    if (lTrashLength > 0)
        {
            pTrashBytes = (BYTE*)VSAlloc(lTrashLength);
            IfNullMemGo(pTrashBytes);
            
            long lDataRead = 0;
            
            hr = pSettings->ReadSettingBytes(c_szRandomTrashLength, pTrashBytes, &lDataRead, lTrashLength);
            IfFailGo(hr);
            
            if (lDataRead != lTrashLength)
    {
        hr = E_UNEXPECTED;
        goto Error;
    }
        }
    
    // Note: before returning these settings should immediately be applied to your personal
    //            settings store, whether in the registry or the file system.
    // This write-thru cache methodology is essential to work in multi-instance IDE scenarios.
    hr = UpdateState_CommandBar(bstrFirstSettingName,lTrashLength,pTrashBytes,lDataRead);
    
 Error:
    return hr;
};

HRESULT ImportSettings_KeyBindings(IVsSettingsReader *pSettings, UserSettingsFlags flags, BOOL *pfRestartRequired)
{
    if (!pSettings)
        return E_INVALIDARG;
    
    if (pfRestartRequired)
        {
            *pfRestartRequired = FALSE; //Nobody should require a restart!!
        }
    
    CComBSTR bstrBreakPointWindow;
    
    // Determines whether to import as an additive operation or a reset all settings operation.
    BOOL fResetCompletely = FALSE; 
    
    if (flags & USF_ResetOnImport)
        fResetCompletely = TRUE;
    
    hr = pSettings->ReadSettingString(c_szBreakPointWindow, &bstrBreakPointWindow);
    IfFailGo(hr);
    
    // Note: before returning these settings should immediately be applied to your personal
    //            settings store, whether in the registry or the file system.
    // This write-thru cache methodology is essential to work in multi-instance IDE scenarios.
    hr = UpdateState_KeyBindings(bstrBreakPointWindow);
    
    
 Error:
    return hr;
}

Siehe auch

Aufgaben

Gewusst wie: und exportieren mithilfe von Interop-Assemblys

Konzepte

Beibehalten von Einstellungen

Weitere Ressourcen

Optionen und Benutzereinstellungen

Working with Settings