將 MFC ActiveX 控件標示為安全的腳本和初始化

本文說明如何將 MFC ActiveX 控件標示為 [腳本和初始化安全]。

原始產品版本: MFC ActiveX 控制件
原始 KB 編號: 161873

摘要

根據預設,MFC ActiveX 控件不會標示為 [腳本安全] 和 [初始化安全]。 當控件在 Internet Explorer 中執行,且安全性層級設定為中或高時,這會變得很明顯。 在任一模式中,可能會顯示警告,指出控件的數據不安全,或控件可能不安全,無法讓腳本使用。

控制件可以使用兩種方法來消除這些錯誤。 第一個涉及實作 介面的 IObjectSafety 控件,對於想要變更其行為的控件很有用,而且如果在因特網瀏覽器的內容中執行,則會變成安全。 第二個動作涉及修改控件的 DllRegisterServer 函式,以在登錄中將控件標示為安全。 本文涵蓋這些方法的第二個。 第一個實作 介面的方法 IObjectSafety 涵蓋在因特網用戶端 SDK 中。

請記住,只有當控件實際上是安全的時,才應該將它標示為安全。 如需相關說明,請參閱因特網用戶端 SDK 檔。 請參閱元件開發一節底下的 ActiveX 控制件安全初始化和腳本

注意事項

本文並未說明如何標示安全的控件以供下載。 如需程式代碼下載和程式代碼簽署的詳細資訊,請參閱因特網用戶端 SDK。

其他相關資訊

請遵循下列步驟,將 MFC ActiveX 控件標示為 [腳本安全] 且 [安全] 以進行初始化:

  1. CreateComponentCategory將下列 cathelp.h 和 cathelp.cpp 檔案新增至專案,以實作 和 RegisterCLSIDInCategory 協助程式函式。

    • Cathelp.h

      #include "comcat.h"
      
      // Helper function to create a component category and associated
      // description
      HRESULT CreateComponentCategory(CATID catid, WCHAR* catDescription);
      
      // Helper function to register a CLSID as belonging to a component
      // category
      HRESULT RegisterCLSIDInCategory(REFCLSID clsid, CATID catid);
      
    • Cathelp.cpp

      #include "comcat.h"
      
      // Helper function to create a component category and associated
      // description
      HRESULT CreateComponentCategory(CATID catid, WCHAR* catDescription)
      {
          ICatRegister* pcr = NULL ;
          HRESULT hr = S_OK ;
      
          hr = CoCreateInstance(CLSID_StdComponentCategoriesMgr,
          NULL,
          CLSCTX_INPROC_SERVER,
          IID_ICatRegister,
          (void**)&pcr);
          if (FAILED(hr))
          return hr;
      
          // Make sure the HKCR\Component Categories\{..catid...}
          // key is registered
          CATEGORYINFO catinfo;
          catinfo.catid = catid;
          catinfo.lcid = 0x0409 ; // english
      
          // Make sure the provided description is not too long.
          // Only copy the first 127 characters if it is
          int len = wcslen(catDescription);
          if (len>127)
          len = 127;
          wcsncpy(catinfo.szDescription, catDescription, len);
          // Make sure the description is null terminated
          catinfo.szDescription[len] = '\0';
      
          hr = pcr->RegisterCategories(1, &catinfo);
          pcr->Release();
      
          return hr;
      }
      
      // Helper function to register a CLSID as belonging to a component
      // category
      HRESULT RegisterCLSIDInCategory(REFCLSID clsid, CATID catid)
      {
          // Register your component categories information.
          ICatRegister* pcr = NULL ;
          HRESULT hr = S_OK ;
          hr = CoCreateInstance(CLSID_StdComponentCategoriesMgr,
          NULL,
          CLSCTX_INPROC_SERVER,
          IID_ICatRegister,
          (void**)&pcr);
          if (SUCCEEDED(hr))
          {
              // Register this category as being "implemented" by
              // the class.
              CATID rgcatid[1] ;
              rgcatid[0] = catid;
              hr = pcr->RegisterClassImplCategories(clsid, 1, rgcatid);
          }
      
          if (pcr != NULL)
          pcr->Release();
      
          return hr;
      }
      
  2. 修改 以 DllRegisterServer 將控件標示為安全。 在專案中的.cpp檔中找出 的 DllRegisterServer 實作。 您必須將數個專案新增至此.cpp檔案。 包含實作 和 RegisterCLSIDInCategoryCreateComponentCategory檔案:

    #include "CatHelp.h"
    

    定義與安全元件類別相關聯的 GUID:

    const CATID CATID_SafeForScripting =
    {0x7dd95801,0x9882,0x11cf,{0x9f,0xa9,0x00,0xaa,0x00,0x6c,0x42,0xc4 }} ;
    const CATID CATID_SafeForInitializing =
    {0x7dd95802,0x9882,0x11cf,{0x9f,0xa9,0x00,0xaa,0x00,0x6c,0x42,0xc4 }} ;
    

    定義與控件相關聯的 GUID。 為了簡單起見,您可以從 IMPLEMENT_OLECREATE_EX 控件主要.cpp檔中的宏借用 GUID。 稍微調整格式,使其看起來如下所示:

    const GUID CDECL BASED_CODE _ctlid =
    { 0x43bd9e45, 0x328f, 0x11d0,
    { 0xa6, 0xb9, 0x0, 0xaa, 0x0, 0xa7, 0xf, 0xc2 } };
    

    若要將控件標示為 [腳本安全] 和 [初始化],請修改 函式, DllRegisterServer 如下所示:

    STDAPI DllRegisterServer(void)
    {
        AFX_MANAGE_STATE(_afxModuleAddrThis);
    
        if (!AfxOleRegisterTypeLib(AfxGetInstanceHandle(), _tlid))
        return ResultFromScode(SELFREG_E_TYPELIB);
    
        if (!COleObjectFactoryEx::UpdateRegistryAll(TRUE))
        return ResultFromScode(SELFREG_E_CLASS);
    
        if (FAILED( CreateComponentCategory(
        CATID_SafeForScripting,
        L"Controls that are safely scriptable")))
        return ResultFromScode(SELFREG_E_CLASS);
    
        if (FAILED( CreateComponentCategory(
        CATID_SafeForInitializing,
        L"Controls safely initializable from persistent data")))
        return ResultFromScode(SELFREG_E_CLASS);
    
        if (FAILED( RegisterCLSIDInCategory(
        _ctlid, CATID_SafeForScripting)))
        return ResultFromScode(SELFREG_E_CLASS);
    
        if (FAILED( RegisterCLSIDInCategory(
        _ctlid, CATID_SafeForInitializing)))
        return ResultFromScode(SELFREG_E_CLASS);
    
        return NOERROR;
    }
    

    您通常不會因為下列兩個原因修改 DllUnregisterServer 函式:

    • 您不想移除元件類別,因為其他控件可能正在使用它。

    • 雖然已定義函式 UnRegisterCLSIDInCategory ,但根據預設 DllUnregisterServer ,會從登錄中完全移除控件的專案。 因此,從控件的註冊中移除類別幾乎沒用。

    編譯並註冊控件之後,您應該會在登錄中找到下列專案:

    • HKEY_CLASSES_ROOT\Component Categories\{7DD95801-9882-11CF-9FA9-00AA006C42C4}

    • HKEY_CLASSES_ROOT\Component Categories\{7DD95802-9882-11CF-9FA9-00AA006C42C4}

    • HKEY_CLASSES_ROOT\CLSID\{"your controls GUID"}\Implemented Categories\{7DD95801-9882-11CF-9FA9-00AA006C42C4}

    • HKEY_CLASSES_ROOT\CLSID\{"your controls GUID"}\Implemented Categories\{7DD95802-9882-11CF-9FA9-00AA006C42C4}

參考資料

因特網用戶端 SDK - 元件開發 - ActiveX 控制件的安全初始化和腳本