【COM实战经验三】:进程外COM内存释放不及时、权限问题导致实例化进程外COM接口失败

参考资料:
https://bbs.csdn.net/topics/391821709?page=1
http://benworld.iteye.com/blog/1988445
https://www.cnblogs.com/baiyanhuang/archive/2009/11/22/1730724.html
在上一篇《32位com调用64位进程外com的例子》中提到进程外COM组件的两种实例化方式
一、 进程外COM内存释放不及时的原因
方法一:创建唯一实例(调用结束后,进程立刻退出)
HRESULT hr = S_FALSE;
hr = hr = CoCreateInstance(
CLSID_TopologyPretreatment,
NULL,
CLSCTX_LOCAL_SERVER,
IID_ITopologyPretreatment,
(void**)&m_pTopPre);

方法二:创建多个实例(调用结束后,进程约30分钟后才退出)
HRESULT hr = S_FALSE;
IClassFactory* pFactory;
hr = CoGetClassObject(CLSID_TopologyPretreatment, CLSCTX_LOCAL_SERVER, NULL, IID_IClassFactory, (LPVOID*)&pFactory);
hr = pFactory->CreateInstance(NULL, IID_ITopologyPretreatment, (void**)&m_pTopPre);

分析为什么采用方法二实例化之后,调用结束,进程没有立刻退出呢?
还未找到原因,后面补充!

二、权限问题导致实例化进程外COM接口失败
首先分析了CoCreateInstance的实现原理,发现与此并无关系。
然后纠结是否是进程外COM导致,发现也说不通。
最后发现出在了exe本身权限上面,原因是在创建进程外COM时,设置了UAC执行权限为【requireAdministrator (/level=‘requireAdministrator’)】导致。将此处的执行权限修改为【asInvoker (/level=‘asInvoker’)】即可。
在这里插入图片描述

三、过程中分析总结
1、CoCreateInstance的内部实现原理
在这里插入图片描述
CoCreateInstance(…)
 {
 //…
 IClassFactory *pClassFactory=NULL;
 CoGetClassObject(CLSID_Object, CLSCTX_INPROC_SERVER, NULL, IID_IClassFactory, (void )&pClassFactory);
 pClassFactory->CreateInstance(NULL, IID_IUnknown, (void
)&pUnk);
 pClassFactory->Release();
 //…
}

2、CoCreateInstance的使用
IUnknown pUnk=NULL;
IObject pObject=NULL;
CoInitialize(NULL);
CoCreateInstance(CLSID_Object, CLSCTX_INPROC_SERVER, NULL, IID_IUnknown, (void
)&pUnk);
pUnk->QueryInterface(IID_IOjbect, (void**)&pObject);
pUnk->Release();
pObject->Func();
pObject->Release();
CoUninitialize();

3、注册表在COM中的重要作用
首先要知道GUID的概念,COM中所有的类、接口、类型库都用GUID来唯一标识,GUID是一个128位的字串,根据特制算法生成的GUID可以保证是全世界唯一的。 COM组件的创建,查询接口都是通过注册表进行的。有了注册表,应用程序就不需要知道组件的DLL文件名、位置,只需要根据CLSID查就可以了。当版本升级的时侯,只要改一下注册表信息就可以神不知鬼不觉的转到新版本的DLL。

4、UAC执行级别
asInvoker (/level=‘asInvoker’) :默认执行级别asInvoker
highestAvailable (/level=‘highestAvailable’) :users组的环境下,执行可执行程序,requireAdministrator会要求输入管理员账号的密码,highestAvailable则会获取当前用户最高权限
requireAdministrator (/level=‘requireAdministrator’):users组的环境下,执行可执行程序,requireAdministrator会要求输入管理员账号的密码,highestAvailable则会获取当前用户最高权限

5、通过工具查询
方法一:任务管理器中,选择列,勾上“特权”一项,在详细信息中就可以看到了
在这里插入图片描述
在这里插入图片描述

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值