在 Visual Studio .Net 部署項目中注冊 COM 模塊的步驟
- 將 COM 對象添加到 Visual Studio 部署項目。
- 在解決方案資源管理器中,右鍵單擊剛添加的模塊,然后單擊屬性。
注意:“屬性”窗口包含一個表,其中有兩列和?x?行(行數取決于項目)。左列列出特定屬性。右列將在步驟 4 中解釋。 - 轉到此模塊的屬性(默認情況下位于 .NET 部署項目的右上角),然后單擊“注冊表屬性”。
注意:注冊表屬性指定在安裝過程中,應將文件、程序集還是項目輸出組注冊在目標計算機上。 - 在注冊表屬性的右列中有一個列表框,它顯示供您選擇的幾個選項。請注意解釋這些選項的下列詳細信息:
- 對于程序集,通常不需要注冊,因而默認值是?DoNotRegister(這意味著安裝過程中不會注冊該項)。
- 對于 COM 模塊,您可以選擇?COM、COMRelativePath?和?COMSelfReg。在安裝過程中,這三個選項中的任何一個都將注冊 COM 模塊。
請注意下列有關每個選項的詳細信息:
- COM:模塊將由 Windows 安裝程序引擎注冊為 COM 對象。部署項目將更新相應 .msi 文件的 Registry Tables 組中的 Class 表、ProgID 表和其他表。這是注冊 COM 模塊的建議方式。
- COMRelativePath:模塊將由 Windows 安裝程序引擎注冊為獨立的 COM 對象。請注意,此模塊只能由安裝它時使用的應用程序所使用。
- COMSelfReg:在安裝模塊時,安裝程序調用此模塊的?DllRegisterServer?函數;在卸載模塊時,安裝程序調用?DllUnregisterServer?函數。部署項目將更新相應 .msi 文件的 SelfReg 表。建議安裝包不要使用自注冊。相反,安裝包應通過創作安裝程序所提供的、用于此用途的一個或多個其他表注冊模塊(即選擇?COM?或COMRelativePath?選項)。對于自注冊,將失去擁有中央安裝程序服務的許多好處,原因是自注冊例程常常會隱藏關鍵配置信息。
現在可以生成部署項目,以允許前面的修改依照在步驟 4 中選擇的注冊屬性選項來注冊 COM 對象。 - 編寫批處理腳本.bat文件,使用regsvr32?/s命令注冊,調用bat腳本。
- 用?LoadLibrary?和?GetProcAddress?取得控件中?DllRegisterServer 函數地址,然后調用注冊。
typedef LONG (*FUN)();
HMODULE hDll = ::LoadLibrary(TEXT("C:\\WINDOWS\\system32\\Macromed\\Flash\\Flash10e.ocx"));
if (!hDll)
return;FUN fn = (FUN)GetProcAddress(hDll, "DllRegisterServer");
if (fn)
{fn();
}
FreeLibrary(hDll);
- 讓應用程序在運行的時候自動檢查所需要的支持文件和注冊控件,免除安裝和手動注冊。適當修改下面的代碼中的支持文件列表,并在App::InitInstance()中調用。
#include <shlwapi.h>
#pragma comment(lib, "shlwapi.lib")//檢測需要的文件是否存在
//并且對需要注冊的文件進行注冊
//輸入參數用于指示文件所在的路徑
//返回TRUE表示成功
BOOL Check_Environment(LPCTSTR lpszAppPath) //傳入文件路徑
{//列出所需要的文件列表typedef struct _FILE_CELL{LPCTSTR szFileName; //文件名BOOL bNeedRegister; //需要注冊?}FILE_CELL;const FILE_CELL Support_FileList[] ={{_T("aaa.ocx"), TRUE}, {_T("bbb.ocx"), TRUE}, {_T("ccc.ocx"), TRUE}, {_T("fff.dll"), TRUE}, {_T("other.sys")}, //other need file0, //Don't remove this line};BOOL bRet = 0;TCHAR e_mess[4096], mess[256];memset(e_mess, 0, sizeof(e_mess));int uIndex = 0;while(Support_FileList[uIndex].szFileName){TCHAR fileName[MAX_PATH + 1];_tcscpy_s(fileName, lpszAppPath);PathAddBackslash(fileName);_tcscat_s(fileName, Support_FileList[uIndex].szFileName);if(PathFileExists(fileName)){//if(_tcsicmp(PathFindExtension(fileName),_T(".ocx"))==0) //是需要注冊的OCX文件if(Support_FileList[uIndex].bNeedRegister) //需要注冊{ //使用短路徑名主要是為兼容Win98TCHAR shortfileName[MAX_PATH + 1];GetShortPathName(fileName, shortfileName, MAX_PATH);// Path to OLE Control in shortfileNameHMODULE hModule = LoadLibrary(shortfileName);if(hModule){typedef HRESULT (STDAPICALLTYPE *CTLREGPROC)() ; // Requires olectl.hCTLREGPROC DLLRegisterServer = (CTLREGPROC)GetProcAddress(hModule,"DllRegisterServer" ) ;if(DLLRegisterServer){if(DLLRegisterServer() != S_OK){_stprintf_s(mess, _T("注冊模塊失敗 %s\r\n"), fileName);_tcscat_s(e_mess, mess);}}else{_stprintf_s(mess, _T("模塊%s找不到指定注冊入口\r\n"), fileName);_tcscat_s(e_mess, mess);}FreeLibrary(hModule) ;}else{_stprintf_s(mess, _T("加載模塊失敗 %s\r\n"), fileName);_tcscat_s(e_mess, mess);}}}else //提示缺少必要的支持文件{_stprintf_s(mess, _T("缺少必要的文件 %s\r\n"), fileName);_tcscat_s(e_mess, mess);}uIndex++;}if(_tcslen(e_mess) > 0) //檢測出錯提示{MessageBox(NULL, e_mess, _T("Error"), MB_OK );}else{bRet = true;}return(bRet);
}
轉載于:https://www.cnblogs.com/yefengmeander/archive/2012/11/29/2887550.html