By SmartPtr(http://www.cppblog.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;
}