SmartPtr
本博客已搬至:http://www.cnblogs.com/baiyanhuang/
posts - 29,comments - 176,trackbacks - 0
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;
}
posted on 2007-07-06 21:30 SmartPtr 阅读(1594) 评论(7)  编辑 收藏 引用

FeedBack:
# re: 如何判断一个COM对象是否可用
2007-07-06 21:36 | 万连文
这个直接看返回值比较好。  回复  更多评论
  
# re: 如何判断一个COM对象是否可用
2007-07-06 21:44 | SmartPtr
假设讲我的COM组件在系统运行一段时间后,在某个操作中才会被创建出来,而此时如果此对象无法创建,系统的任务就无法完成,此时用户就要问了:“早干嘛去了,先让我瞎忙活那么长时间, 不行早说嘛”, 呵呵,开个玩笑, 其实这就是我们同事遇到的现实问题。 但如果我在一开始就试图创建全部的COM对象而只为了判断其是否可创建,似乎消耗大了点,逻辑上也不太合理。  回复  更多评论
  
# re: 如何判断一个COM对象是否可用
2007-07-06 23:36 | DC
我觉得也是直接看返回值比较好,因为你的这个操作只能确认COM对象是否存在,至于能否创建成功还不一定。  回复  更多评论
  
# re: 如何判断一个COM对象是否可用
2007-07-07 20:07 | 万连文
对一种技术的滥用,不规范使用是需要制止而不是想办法包庇纵容,那样只会是的系统越来越糟糕。  回复  更多评论
  
# re: 如何判断一个COM对象是否可用
2007-07-07 20:17 | SmartPtr
to 万连文
可否解释一下, 实在是看不明白。。。。。  回复  更多评论
  
# re: 如何判断一个COM对象是否可用
2007-07-09 09:53 | SuperPlayeR
我个人理解万连文的意思就是说,针对你讲述的这种情况,实际是因为com组件没有被注册造成了,而显然使用COM技术的规范性操作当然是先注册这个组件再使用。而博主您的想法也是通过读取注册表看该组件是否注册了,其实也是一种不规范使用。  回复  更多评论
  
# re: 如何判断一个COM对象是否可用
2007-07-09 19:54 | SmartPtr
To SuperPlyeR:

不仅是没有注册造成的, 应该说是某些异常操作使得该COM组件不可用, 可以是没有注册,也可以是注册后注册信息被误操作覆盖, 也可以是该DLL被删除, 总之, 在系统运行之前先检测一下这些东西是否都是ready的, 如果不是, 那就不要进去先。

之前有朋友说直接创建该COM对象来判断, 但我觉得创建组件只是去做判断,不太可取  回复  更多评论
  

只有注册用户登录后才能发表评论。
【推荐】超50万行VC++源码: 大型组态工控、电力仿真CAD与GIS源码库
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理