如何判斷一個COM物件是否可用
阿新 • • 發佈:2018-12-27
同事工作中遇到這個問題,不想在建立物件失敗時才知道原來對應的COM物件不可用。自己專案中用到了這個,遂總結一下,希望對大家有用。
要判斷一個COM物件是否有用,首先要判斷該COM物件的CLSID是否在登錄檔中註冊,但註冊了並不能保證其可用,因為如果我誤刪了該COM物件的載體-DLL(或exe),該COM物件仍然不能正確建立。所以我們還要判斷該載體檔案是否存在,兩者都通過了,該COM物件才可正確建立。
直接看程式碼:
bool IsCOMAvailable(CString strGUID)
{
// 1. Try to open the HKEY_CLASSES_ROOT\CLSID\{xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx} key CString strKeyName = _T("CLSID\\") + strGUID;
HKEY hClsidKey;
if( ::RegOpenKeyEx( HKEY_CLASSES_ROOT, strKeyName, 0, KEY_QUERY_VALUE, &hClsidKey ) == ERROR_SUCCESS )
{
// 2. Continue to open CLSID\{xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx}\InProcServer32\(Default) HKEY hInProcServer32Key;
if( ::RegOpenKeyEx( hClsidKey, _T( "InProcServer32" ), 0, KEY_QUERY_VALUE, &hInProcServer32Key ) == ERROR_SUCCESS )
{
TCHAR tszServerPathName[_MAX_PATH];
DWORD dwSize =sizeof( tszServerPathName );
DWORD dwType;
// 3. Get the com dll pathif( ::RegQueryValueEx( hInProcServer32Key, NULL, NULL, &dwType, (LPBYTE)tszServerPathName, &dwSize ) == ERROR_SUCCESS )
{
if( dwType != REG_SZ )
returnfalse;
// 4. If the dll file exist CFileFind fileFind;
if(fileFind.FindFile(tszServerPathName))
returntrue;
}
::CloseHandle(hInProcServer32Key);
}
::CloseHandle(hClsidKey);
}
returnfalse;
}
要判斷一個COM物件是否有用,首先要判斷該COM物件的CLSID是否在登錄檔中註冊,但註冊了並不能保證其可用,因為如果我誤刪了該COM物件的載體-DLL(或exe),該COM物件仍然不能正確建立。所以我們還要判斷該載體檔案是否存在,兩者都通過了,該COM物件才可正確建立。
直接看程式碼:
bool IsCOMAvailable(CString strGUID)
{
// 1. Try to open the HKEY_CLASSES_ROOT\CLSID\{xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx} key
HKEY hClsidKey;
if( ::RegOpenKeyEx( HKEY_CLASSES_ROOT, strKeyName, 0, KEY_QUERY_VALUE, &hClsidKey ) == ERROR_SUCCESS )
{
// 2. Continue to open CLSID\{xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx}\InProcServer32\(Default) HKEY hInProcServer32Key;
{
TCHAR tszServerPathName[_MAX_PATH];
DWORD dwSize =sizeof( tszServerPathName );
DWORD dwType;
// 3. Get the com dll pathif( ::RegQueryValueEx( hInProcServer32Key, NULL, NULL,
{
if( dwType != REG_SZ )
returnfalse;
// 4. If the dll file exist CFileFind fileFind;
if(fileFind.FindFile(tszServerPathName))
returntrue;
}
::CloseHandle(hInProcServer32Key);
}
::CloseHandle(hClsidKey);
}
returnfalse;
}