上一篇文章简单演示了COM组件的编写,注册及调用,本篇实现COM的自注册和反注册
1. 实现COM组件的自注册和反注册
实现COM组件的自注册和反注册,本质上就是写注册表与删注册表。需要在DLL中引出两个函数:DllRegisterServer和DllUnregisterServer,让这两个函数实现注册表操作。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61
| LPCTSTR RegTable[][3] = { {L"CLSID\\{586CDC7B-09F1-4f44-A110-F0E604AED81E}", 0, L"BeginningCOM"}, {L"CLSID\\{586CDC7B-09F1-4f44-A110-F0E604AED81E}\\InprocServer32", 0, (LPCTSTR)-1}, {L"CLSID\\{586CDC7B-09F1-4f44-A110-F0E604AED81E}\\InprocServer32", L"ThreadingModel", L"Both"} };
STDAPI DllUnregisterServer() { HRESULT hr = S_OK;
int regCount = sizeof(RegTable) / sizeof(*RegTable);
for(int i = regCount - 1; i >= 0; i--) { LSTATUS error = RegDeleteKey(HKEY_CLASSES_ROOT, RegTable[i][0]);
if(error != ERROR_SUCCESS) { hr = S_FALSE; } }
return hr; }
STDAPI DllRegisterServer(void) { HRESULT hr = S_OK; TCHAR szFileName[MAX_PATH];
ZeroMemory(&szFileName, MAX_PATH * sizeof(TCHAR));
GetModuleFileName(g_hModule, szFileName, MAX_PATH);
int regCount = sizeof(RegTable) / sizeof(*RegTable);
for(int i = 0; i < regCount; i++) { if(RegTable[i][2] == (LPCTSTR)-1) { RegTable[i][2] = szFileName; }
HKEY hKey; LSTATUS error = ::RegCreateKey(HKEY_CLASSES_ROOT, RegTable[i][0], &hKey);
if(error == ERROR_SUCCESS) { error = RegSetValueEx(hKey, RegTable[i][1], 0, REG_SZ, (const BYTE*)RegTable[i][2], (lstrlen(RegTable[i][2]) + 1) * sizeof(TCHAR)); RegCloseKey(hKey); }
if(error != ERROR_SUCCESS) { DllUnregisterServer(); } }
return hr; }
|
现将需要修改的注册表内容放到一个二维数组中,第一维内容分别是注册表键,项,值。-1为占位符,标识该位置放置COM组件的路径,在写注册表之前将其替换。
删注册表时,应该先删子键,否则删除会失败。
同时需要在BeginningCOM.def中导出这两个函数:
1 2 3 4 5
| LIBRARY "BeginningCOM" EXPORTS DllGetClassObject private DllRegisterServer private DllUnregisterServer private
|
这样就可以用regsvr32.exe注册和反注册COM组件。