如何在运行期发现com,实现插件功能

 我来答
miniappYoh44tFFDbwZi
2016-03-06 · 请开发者输入账号签名
miniappYoh44tFFDbwZi
采纳数:14074 获赞数:18291

向TA提问 私信TA
展开全部
1 找出其中支持COM的 DLL比较容易,只要挨个LoadLibary然后看有没有DllRegisterServer就可以了.
2 找某个组件中的COM的CLSID不容易,你只能通过几个办法:
(1),如果有.tlb文件,可以把tlb反编译成idl文件,然后在idl中查找CoClass.反编译代码在网很多,也可以直接用VC提供的工具好象叫TLB*.exe
(2)如果没有.tlb,用同样方法看一下类型库信息有没有被编译在dll中.
(3)如果找不到类型库信息,没办法只好去注册表中找,先注册一下这个DLL(regsvr32 this.dll,或直接调用上面得到的DllRegisterServer),然后到注册表的CLSID找哪些CLSID中包含this.dll.
3 找到CLSID后就可以创建组件了,可以直接CoCreateInstance,也可以得到DLL中的DllGetClassObject
然后创建一个IUnknown,然后查找你要的接口.
4 如果你连调用什么接口什么方法都不知道,那就不要做了.你总不能总是传NULL给方法吧.

接口肯定是知道的.那就是自己定义的阿.为了实现插件功能,所有的dll都实现了同样的接口tlb肯定是没有的,
就算有,你那个方法也是不可行的.那是我自己的插件那!我要在运行的时候,扫描plugin目录
找到所有的dll,取得dll的信息(创建了他的事例并调了某个函数),以某种形式显示在界面上。
当用户选用这种功能时,我就使用他/
我不能让用户,下载了一个插件后,就去反编译他的tlb
要在编程阶段找出所有的dll的接口之类,都是非常容易的事情。
我要的是运行期的效果。你说的意思我没大听明白,要发现一个dll是不是要这样?
1 注册他.
2 搜索和遍历老长,老长的注册表,看哪一项有这个dll,找到clid
3 根据接口id和clid得到事例.
看起来好像绕了一个大大的弯子。我相信正解一定不会是这样。

1)反编译库型库信息其实只是得到一个接口然后去查询信息,只要调LoadTypeLib就可以了.
2)如果你不能得到类型库信息,你就只有用搜索注册表,除此之外绝对没有别的办法.
单从COM的DLL中再怎么折腾也得不到CLSID(当然不包括CLSID_Factory之类的).
我以前试过一个办法就是分析DLL文件,可以在里面找到ProgIDCurVerA1Svr.Fun{969E8460-D5CB-4690-A566-A7E2E9095D5D}但这个信息在不同开发环境生成的DLL中会不同,所以不完全.你说DLL是你自己写的.如果要找的DLL是你自己写的那还有什么困难?

我没有说过dll是自己写得阿我说接口是自己定义的。不过谢谢您的关注,我会给分的

关键是解决问题呀。20分有什么用?
以前我帮导师写过一个类似OleView的东西,和OleView不同的是要查看的DLL都是没有注册的。当时我也是为得到clsid头痛了一个多月,最终没办法还是用ITypeLib来得到的,但有时没有类型库信息,我就没办法了。
等待大牛出现,现身说法!

我想了一个办法可以解决我的插件问题了
1 要求提供插件的人同时提供配置文件 比如 (xxx.dll,xxx.conf)
配置文件里包含CLID(因为是做插件,所以接口ID是固定的)
2 安装插件的时候,将dll注册
3 使用插件的时候,读取所有的配置文件,根据配置文件创建com对象 没有试过,实践是检验真理的唯一标准。我去试试你的那个问题,我搜了几个帖子,大概的意思是:用IDispatch 的Invoke
还有一个有趣的函数
CLSIDFromProgID
eg: CLSID clsid;
CLSIDFromProgID(L"testcom1.testget", &clsid);
url:
http://61.186.252.131/Expert/topic/1074/1074122.xml?temp=.5610315
http://61.186.252.131/Expert/topic/2175/2175865.xml?temp=.1130945

想实现插件模式我觉得word和ie的模式够好了!
1、首先它在注册表中留有一个设置插件的主建,
2、每个插件都在这里放着自己的clsid和progid等主要信息
3、word运行时会找注册表的该主键遍历创建之!它放在哪里并不关心
4、word的每个插件都要实现固定一个接口的实现起到了互相挂接的目的
现在是不是应该知道怎么做了吧!
TaiJi1985是不是在太极连工作呢!hoho!

你可以让所有的插件DLL都实现一个输出函数,通过这个函数取得CLSID。
我说的这个输出函数是普通DLL的输出函数,和COM没有关系。

首先,符合你的程序件的com都要实现预定义的接口,这个接口是你定义的,接口ID是已知的,你只要load这些com组件,通过iDispatch接口查看类型库信息,找到存在的接口ID就表明是这个程序的插件,然后通过类型库查询到class ID(可能不止一个),都用coCreateInstance创建object就行了。注意这些com要在程序安装的时候注册先

如果com不支持iDispatch接口,可以将插件的class ID事先保存在配置文件或注册表中,程序启动时读出这些class ID,配合接口ID用coCreateInstance创建object就行了

我的问题有人能帮我看看吗?就是给出一个COM的DLL或OCX,到里面所有的CLSID

一般COM的DLL或OCX都带了typelibrary,你可以用LoadTypeLib/LoadTypeLibEx打开它得到需要的信息
参考www.codeguru.com/Cpp/COM-Tech/atl/atl/article.php/c57/
CodeGuru: An ATL Project to View Type Libraries

谢谢各位,没想到有那么多好的办法 ,我总结一下各位的思路把。1 CLSID要求插件提供者提供,至于存储的位置,可以是
配置文件(我)
注册表 (wangweixing2000)
共同的dll输出函数( nelsonc(软件兔) ) 我觉得软件兔的方法比较好,不用特殊的安装程序直接用regsvr32就搞定了
注册表的方法得到插件需要用自己写得安装程序添注册表.但是一个好处是和插件的位置无关,其他两种办法都需要放到特定的目录
我想的那个配置文件。 那时绝对的慢,不好,准备用软件兔的办法2 这些插件都实现同样的接口(
好办法,不过怎么样操作?
用ATL作的时候,新建一个ATL对象,就会同时创建一个接口和
一个对象,我试着强行把两个对象改称一个对象,结果好像出现了
重定义的错误.
用vb就更不用说了,连接口是什么样子都不给看,直接一个对象
)
这些插件实现的接口是继承自同一个接口.
这个绝对是可行的阿.
不过我还是不知道怎么操作!

请各位大虾教一教我.
比如用vc定义了一个接口,用vb定义一个这个接口的子接口的对象.3 使用iDispatch,调用插件
谢谢

用oleview可以看到的,有写com是在同一个catalog底下,这些就是同一种类型的com,应该是他们具有统一的调用方式,通过列举该catalog下所有的com来找到已经安装的插件,逐个调用。实际上com就是全局的类,谁都可以调用,先实现类厂,然后再用类厂的GetObject来得到函数对象,这时候如果你把所有的统一行为的类设置成同样的GUID,应该就可以了,如果就只有一个用IUnkown不就可以了,就是:
类厂:GUID_ABC{12345....}
其中的接口:IID_A{.....1},IID_B{....2}...
类厂:GUID_BCD{123456...}
其中的接口:IID_A{.....1},IID_B{....2}...
接口的GUID都一样,调用的时候只需要用CLIDFromProgID把不同插件的ProgramID拿出来不就可以了
微测检测5.10
2023-05-10 广告
您好!建议咨 深圳市微测检测有限公司,已建立起十余个专业实验室,企业通过微测检测就可以获得一站式的测试与认 证解决方案;(EMC、RF、MFi、BQB、QI、USB、安全、锂电池、快充、汽车电子EMC、汽车手机互 联、语音通话质量),认证遇... 点击进入详情页
本回答由微测检测5.10提供
推荐律师服务: 若未解决您的问题,请您详细描述您的问题,通过百度律临进行免费专业咨询

为你推荐:

下载百度知道APP,抢鲜体验
使用百度知道APP,立即抢鲜体验。你的手机镜头里或许有别人想知道的答案。
扫描二维码下载
×

类别

我们会通过消息、邮箱等方式尽快将举报结果通知您。

说明

0/200

提交
取消

辅 助

模 式