DLL做好之后就可以实现注册代码了,注册之后客户端就可以通过注册表查询到该DLL并进行调用。下面是注册过程,其中使用的两个文件如下:
- //-----------------------------------------------------------------------------
- // File: registry.h
- //
- // Desc: Contains COM register and unregister functions for the UI.
- //
- // Copyright (C) 1999-2001 Microsoft Corporation. All Rights Reserved.
- //-----------------------------------------------------------------------------
- #ifndef __Registry_H__
- #define __Registry_H__
- // This function will register a component in the Registry.
- // The component calls this function from its DllRegisterServer function.
- HRESULT RegisterServer(HMODULE hModule,
- const CLSID& clsid,
- LPCTSTR szFriendlyName,
- LPCTSTR szVerIndProgID,
- LPCTSTR szProgID);
- // This function will unregister a component. Components
- // call this function from their DllUnregisterServer function.
- HRESULT UnregisterServer(const CLSID& clsid,
- LPCTSTR szVerIndProgID,
- LPCTSTR szProgID);
- #endif
- //
- // Registry.cpp
- //
- #include "stdafx.h"
- #include <objbase.h>
- #include <assert.h>
- #include "registry.h"
- #pragma warning(disable:4996)
- //
- // Internal helper functions prototypes
- //
- // Set the given key and its value.
- BOOL setKeyAndValue(const char* pszPath,
- const char* szSubkey,
- const char* szValue);
- // Convert a CLSID into a char string.
- void CLSIDtochar(const CLSID& clsid,
- char* szCLSID,
- int length);
- // Delete szKeyChild and all of its descendents.
- LONG recursiveDeleteKey(HKEY hKeyParent, const char* szKeyChild);
- //
- // Constants
- //
- // Size of a CLSID as a string
- const int CLSID_STRING_SIZE = 39;
- /
- //
- // Public function implementation
- //
- //
- // Register the component in the registry.
- //
- HRESULT RegisterServer(HMODULE hModule, // DLL module handle
- const CLSID& clsid, // Class ID
- const char* szFriendlyName, // Friendly Name
- const char* szVerIndProgID, // Programmatic
- const char* szProgID) // IDs
- {
- // Get server location.
- char szModule[512];
- DWORD dwResult = ::GetModuleFileName(hModule, szModule, sizeof(szModule)/sizeof(char));
- assert(dwResult != 0);
- // Convert the CLSID into a char.
- char szCLSID[CLSID_STRING_SIZE];
- CLSIDtochar(clsid, szCLSID, sizeof(szCLSID));
- // Build the key CLSID//{...}
- char szKey[64];
- strcpy(szKey, "CLSID//");
- strcat(szKey, szCLSID);
- // Add the CLSID to the registry.
- setKeyAndValue(szKey, NULL, szFriendlyName);
- // Add the server filename subkey under the CLSID key.
- setKeyAndValue(szKey, "InprocServer32", szModule);
- // Add the ProgID subkey under the CLSID key.
- setKeyAndValue(szKey, "ProgID", szProgID);
- // Add the version-independent ProgID subkey under CLSID key.
- setKeyAndValue(szKey, "VersionIndependentProgID", szVerIndProgID);
- // Add the version-independent ProgID subkey under HKEY_CLASSES_ROOT.
- setKeyAndValue(szVerIndProgID, NULL, szFriendlyName);
- setKeyAndValue(szVerIndProgID, "CLSID", szCLSID);
- setKeyAndValue(szVerIndProgID, "CurVer", szProgID);
- // Add the versioned ProgID subkey under HKEY_CLASSES_ROOT.
- setKeyAndValue(szProgID, NULL, szFriendlyName);
- setKeyAndValue(szProgID, "CLSID", szCLSID);
- return S_OK;
- }
- //
- // Remove the component from the registry.
- //
- LONG UnregisterServer(const CLSID& clsid, // Class ID
- const char* szVerIndProgID, // Programmatic
- const char* szProgID) // IDs
- {
- // Convert the CLSID into a char.
- char szCLSID[CLSID_STRING_SIZE];
- CLSIDtochar(clsid, szCLSID, sizeof(szCLSID));
- // Build the key CLSID//{...}
- char szKey[64];
- strcpy(szKey, "CLSID//");
- strcat(szKey, szCLSID);
- // Delete the CLSID Key - CLSID/{...}
- LONG lResult = recursiveDeleteKey(HKEY_CLASSES_ROOT, szKey);
- assert((lResult == ERROR_SUCCESS) || (lResult == ERROR_FILE_NOT_FOUND)); // Subkey may not exist.
- // Delete the version-independent ProgID Key.
- lResult = recursiveDeleteKey(HKEY_CLASSES_ROOT, szVerIndProgID);
- assert((lResult == ERROR_SUCCESS) || (lResult == ERROR_FILE_NOT_FOUND)); // Subkey may not exist.
- // Delete the ProgID key.
- lResult = recursiveDeleteKey(HKEY_CLASSES_ROOT, szProgID);
- assert((lResult == ERROR_SUCCESS) || (lResult == ERROR_FILE_NOT_FOUND)); // Subkey may not exist.
- return S_OK;
- }
- ///
- //
- // Internal helper functions
- //
- // Convert a CLSID to a char string.
- void CLSIDtochar(const CLSID& clsid,
- char* szCLSID,
- int length)
- {
- assert(length >= CLSID_STRING_SIZE);
- // Get CLSID
- LPOLESTR wszCLSID = NULL;
- HRESULT hr = StringFromCLSID(clsid, &wszCLSID);
- assert(SUCCEEDED(hr));
- // Covert from wide characters to non-wide.
- wcstombs(szCLSID, wszCLSID, length);
- // Free memory.
- CoTaskMemFree(wszCLSID);
- }
- //
- // Delete a key and all of its descendents.
- //
- LONG recursiveDeleteKey(HKEY hKeyParent, // Parent of key to delete
- const char* lpszKeyChild) // Key to delete
- {
- // Open the child.
- HKEY hKeyChild;
- LONG lRes = RegOpenKeyEx(hKeyParent, lpszKeyChild, 0, KEY_ALL_ACCESS, &hKeyChild);
- if(lRes != ERROR_SUCCESS)
- {
- return lRes;
- }
- // Enumerate all of the decendents of this child.
- FILETIME time;
- char szBuffer[256];
- DWORD dwSize = 256;
- while(RegEnumKeyEx(hKeyChild, 0, szBuffer, &dwSize, NULL, NULL, NULL, &time) == S_OK)
- {
- // Delete the decendents of this child.
- lRes = recursiveDeleteKey(hKeyChild, szBuffer);
- if(lRes != ERROR_SUCCESS)
- {
- // Cleanup before exiting.
- RegCloseKey(hKeyChild);
- return lRes;
- }
- dwSize = 256;
- }
- // Close the child.
- RegCloseKey(hKeyChild);
- // Delete this child.
- return RegDeleteKey(hKeyParent, lpszKeyChild);
- }
- //
- // Create a key and set its value.
- // - This helper function was borrowed and modifed from
- // Kraig Brockschmidt's book Inside OLE.
- //
- BOOL setKeyAndValue(const char* szKey,
- const char* szSubkey,
- const char* szValue)
- {
- HKEY hKey;
- char szKeyBuf[1024];
- // Copy keyname into buffer.
- strcpy(szKeyBuf, szKey);
- // Add subkey name to buffer.
- if(szSubkey != NULL)
- {
- strcat(szKeyBuf, "//");
- strcat(szKeyBuf, szSubkey );
- }
- // Create and open key and subkey.
- long lResult = RegCreateKeyEx(HKEY_CLASSES_ROOT, szKeyBuf, 0, NULL, REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL, &hKey, NULL);
- if(lResult != ERROR_SUCCESS)
- {
- return FALSE;
- }
- // Set the Value.
- if(szValue != NULL)
- {
- RegSetValueEx(hKey, NULL, 0, REG_SZ, (BYTE *)szValue, (DWORD)strlen(szValue)+1);
- }
- RegCloseKey(hKey);
- return TRUE;
- }
registry.h和Registry.cpp两个文件实现对一个进程内COM组件的注册。
现对注册函数修改如下:
- STDAPI DllUnregisterServer(void)
- {
- return UnregisterServer(CLSID_MyCOM, VerIndProgID, ProgID);
- }
- STDAPI DllRegisterServer(void)
- {
- return RegisterServer(g_hInstance, CLSID_MyCOM, FriendlyName, VerIndProgID, ProgID);
- }
经过上述步骤DLL的注册已经实现,可以使用regsvr32 mycom.dll进行注册了。
其中CLSID_MyCOM, FriendlyName, VerIndProgID, ProgID等定义如下:
- // {85F5CF11-2A25-4ef9-8F7C-8C3F14A0860A}
- static const GUID CLSID_MyCOM =
- { 0x85f5cf11, 0x2a25, 0x4ef9, { 0x8f, 0x7c, 0x8c, 0x3f, 0x14, 0xa0, 0x86, 0xa } };
- #define ProgID "MyCOM.CTest.1"
- #define VerIndProgID "MyCOM.CTest"
- #define FriendlyName "MyCOM CTest Sample Provider"
CLSID_MyCOM :组件ID
ProgID:程序ID
VerIndProgID:版本无关的程序ID
FriendlyName:组件描述