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

TaiJi1985 2005-08-11 10:11:15
我想要实现这样一种功能

程序在运行的时候发现一个目录下所有存在的dll,找出其中的com,并调用它

简单一句话,就是用com实现插件.

使用后期邦定的com可以替换,实现升级功能.
但是如何实现这种动态时的发现呢

一般的dll,是很容易实现的,给loadlibary传一个字符串就行了,com呢?
可不会是一般dll那么简单了吧.
...全文
302 16 打赏 收藏 转发到动态 举报
写回复
用AI写文章
16 条回复
切换为时间正序
请发表友善的回复…
发表回复
TaiJi1985 2005-08-15
  • 打赏
  • 举报
回复
不等了,结帐!
魔芋 2005-08-13
  • 打赏
  • 举报
回复
用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拿出来不就可以了
TaiJi1985 2005-08-13
  • 打赏
  • 举报
回复
问题似乎还在雾中,讨论还得继续

如何继承接口,请高手指教
opentuxedo 2005-08-12
  • 打赏
  • 举报
回复
我的问题有人能帮我看看吗?就是给出一个COM的DLL或OCX,到里面所有的CLSID
吹泡泡的小猫 2005-08-12
  • 打赏
  • 举报
回复
如果com不支持iDispatch接口,可以将插件的class ID事先保存在配置文件或注册表中,程序启动时读出这些class ID,配合接口ID用coCreateInstance创建object就行了
吹泡泡的小猫 2005-08-12
  • 打赏
  • 举报
回复
首先,符合你的程序件的com都要实现预定义的接口,这个接口是你定义的,接口ID是已知的,你只要load这些com组件,通过iDispatch接口查看类型库信息,找到存在的接口ID就表明是这个程序的插件,然后通过类型库查询到class ID(可能不止一个),都用coCreateInstance创建object就行了。

注意这些com要在程序安装的时候注册先
nelsonc 2005-08-12
  • 打赏
  • 举报
回复
你可以让所有的插件DLL都实现一个输出函数,通过这个函数取得CLSID。
我说的这个输出函数是普通DLL的输出函数,和COM没有关系。
wangweixing2000 2005-08-12
  • 打赏
  • 举报
回复
想实现插件模式我觉得word和ie的模式够好了!
1、首先它在注册表中留有一个设置插件的主建,
2、每个插件都在这里放着自己的clsid和progid等主要信息
3、word运行时会找注册表的该主键遍历创建之!它放在哪里并不关心
4、word的每个插件都要实现固定一个接口的实现起到了互相挂接的目的
现在是不是应该知道怎么做了吧!
TaiJi1985是不是在太极连工作呢!hoho!
TaiJi1985 2005-08-12
  • 打赏
  • 举报
回复
谢谢各位,没想到有那么多好的办法 ,我总结一下各位的思路把。

1 CLSID要求插件提供者提供,至于存储的位置,可以是
配置文件(我)
注册表 (wangweixing2000)
共同的dll输出函数( nelsonc(软件兔) )

我觉得软件兔的方法比较好,不用特殊的安装程序直接用regsvr32就搞定了
注册表的方法得到插件需要用自己写得安装程序添注册表.但是一个好处是和插件的位置无关,其他两种办法都需要放到特定的目录
我想的那个配置文件。 那时绝对的慢,不好,准备用软件兔的办法

2 这些插件都实现同样的接口(
好办法,不过怎么样操作?
用ATL作的时候,新建一个ATL对象,就会同时创建一个接口和
一个对象,我试着强行把两个对象改称一个对象,结果好像出现了
重定义的错误.
用vb就更不用说了,连接口是什么样子都不给看,直接一个对象
)
这些插件实现的接口是继承自同一个接口.
这个绝对是可行的阿.
不过我还是不知道怎么操作!

请各位大虾教一教我.
比如用vc定义了一个接口,用vb定义一个这个接口的子接口的对象.

3 使用iDispatch,调用插件


谢谢
masterz 2005-08-12
  • 打赏
  • 举报
回复
一般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
TaiJi1985 2005-08-11
  • 打赏
  • 举报
回复
我想了一个办法可以解决我的插件问题了
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


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

我说接口是自己定义的。

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

你说DLL是你自己写的.如果要找的DLL是你自己写的那还有什么困难?
TaiJi1985 2005-08-11
  • 打赏
  • 举报
回复
接口肯定是知道的.那就是自己定义的阿.为了实现插件功能,所有的dll都实现了同样的接口

tlb肯定是没有的,
就算有,你那个方法也是不可行的.那是我自己的插件那!我要在运行的时候,扫描plugin目录
找到所有的dll,取得dll的信息(创建了他的事例并调了某个函数),以某种形式显示在界面上。
当用户选用这种功能时,我就使用他/
我不能让用户,下载了一个插件后,就去反编译他的tlb
要在编程阶段找出所有的dll的接口之类,都是非常容易的事情。
我要的是运行期的效果。



你说的意思我没大听明白,要发现一个dll是不是要这样?
1 注册他.
2 搜索和遍历老长,老长的注册表,看哪一项有这个dll,找到clid
3 根据接口id和clid得到事例.
看起来好像绕了一个大大的弯子。我相信正解一定不会是这样。
opentuxedo 2005-08-11
  • 打赏
  • 举报
回复
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给方法吧.

3,245

社区成员

发帖
与我相关
我的任务
社区描述
ATL,Active Template Library活动(动态)模板库,是一种微软程序库,支持利用C++语言编写ASP代码以及其它ActiveX程序。
社区管理员
  • ATL/ActiveX/COM社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧