共用方式為


How to: 使用 Interop 組件匯入設定

VSPackage 可匯入設定值來源Visual Studio整合式的開發環境 (IDE)。 IDE 會使用 VSPackage 實作的IVsUserSettings介面,以決定要如何擷取 VSPackage 的組態。

注意事項注意事項

管理套件架構 (MPF) 提供一組受管理的類別,可讓您方便建立 Visual Studio 的副檔名。若要執行這項工作使用 MPF,請參閱How to: 使用受管理的封裝架構來匯入設定

若要實作在 VSPackage 上的設定匯入

  1. 實作基本支援Visual Studio設定的機制。

    • 登錄 VSPackage 為支援的設定機制,藉由定義一或多個自訂設定的點。

      如需詳細資訊,請參閱 保存的設定

    • 宣告會實作 VSPackage IVsUserSettings介面,舉個例說:

      public class MyPackage : IVsPackage, IVsUserSettings, IVsUserSettingsQuery
      
    • 確保 VSPackage 實作的QueryInterface方法提供IVsUserSettings介面的呼叫時IID_IVsUserSettings。 例如:

      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. 擷取設定資訊。

    若要支援擷取設定資訊,就必須實作 VSPackage ImportSettings方法。

    若要讀取的資料,VSPackage 實作的IVsUserSettings介面必須使用兩個 ide 傳入的引數: 該自訂設定點類別的 GUID 及IVsSettingsReader介面。

    1. 實作 VSPackage ImportSettings方法必須檢查傳入的 GUID] 類別,然後選擇正確的機制,來擷取狀態。

      在 [範例所示, ImportSettings方法會呼叫不同的實作來擷取命令列狀態,相較於擷取索引鍵繫結狀態。

    2. VSPackage 必須使用所提供IVsSettingsReader介面,以擷取設定檔的資料。

      注意事項注意事項

      如果此類設定變更為函式的Visual Studio版本、 VSPackage 實作的ImportSettings的方法必須使用ReadFileVersion才能讀取資料,以檢查 IDE 版本的方法。

      此介面提供方法來讀取設定檔中的不同資料型別。

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

      };

    設定檔支援隨機資料存取,因此順序讀取及寫入 [設定作業並不重要。

    說明這一點的匯出和匯入命令列的狀態 (ExportSettings_CommandBar 和ImportSettings_CommandBar) 的下面這個範例中的實作。

  3. 驗證擷取的資料。

    可以手動編輯的 XML 檔案中包含的設定資訊。

安全性注意事項安全性提示

設定資訊可能會損毀磁碟上,可以包含版本特有的設定,而且可用來做為一種工具,惡意的攻擊。每個所傳回的資料項目的有效性IVsSettingsReader應該驗證方法。

  • 若要確認支援版本的Visual Studio用來產生擷取的設定,呼叫ReadFileVersion方法來擷取版本。

  • 若要引發通知使用者並不會驗證匯入的資料元素的 IDE,呼叫 VSPackage ReportError方法。

  1. 套用設定的資訊。

    1. 實作ImportSettings方法必須遵守 IDE 傳遞給它的第三個引數的值。 支援的值屬於__UserSettingsFlags列舉型別。 如需詳細資訊,請參閱 __UserSettingsFlags

      下面的命令列設定的匯入的實作範例 (ImportSettings_Commandbar) 來決定是否要套用覆寫現有的值,或 additively 會自動更新這些設定會使用此引數的值。

    2. 套用匯入設定時,您就必須實作一套寫出快取的方法。

      必須同時更新登錄或檔案系統中的狀態資訊,如設定適用於 IDE。 這可確保設定的一致性,並支援多個執行個體 IDE 案例。

  2. 警示 IDE 設定匯入的處理方式。

    使用傳回pfRestartRequired引數的ImportSettings ,如果重新啟動電腦,才能套用匯入的設定 [宣布 IDE 的方法。

    如果實作 VSPackage ImportSettings方法傳回true,系統會提示使用者重新啟動 IDE。

範例

本範例將示範如何匯入和匯出設定的資料。

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;
}

請參閱

工作

How to: 使用 Interop 組件匯出設定

概念

保存的設定

其他資源

使用者設定和選項

Working with Settings