By SmartPtr(http://www.shnenglu.com/SmartPtr/)
同事工作中遇到這個問題,不想在創建對象失敗時才知道原來對應的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 path
if( ::RegQueryValueEx( hInProcServer32Key, NULL, NULL, &dwType, (LPBYTE)tszServerPathName, &dwSize ) == ERROR_SUCCESS )
{
if( dwType != REG_SZ )
return false;
// 4. If the dll file exist
CFileFind fileFind;
if(fileFind.FindFile(tszServerPathName))
return true;
}
::CloseHandle(hInProcServer32Key);
}
::CloseHandle(hClsidKey);
}
return false;
}