2009-09-02 63 views
0

首先,我想说明的是,我需要使用COM/OLE2 API,低级别的东西,可以放在C Windows控制台程序中的东西。我无法使用MFC。我无法使用.NET。重新连接到流程开始通过COM

我的问题是:

考虑下面的代码:

CLSID clsid;  
HRESULT hr; 

hr = CLSIDFromProgID(L"InternetExplorer.Application", &clsid); 
assert(SUCCEEDED(hr)); 

hr = CoCreateInstance(clsid, 
         NULL, 
         CLSCTX_LOCAL_SERVER, 
         IID_IDispatch, 
         (void **)&(iePtr_)); 
assert(SUCCEEDED(hr)); 

是否有写一些信息到磁盘,以便我可以重新连接到IE浏览器的同一个实例以后一种方式?基本上可以将“iePtr_”串联起来以便稍后通过其他一些流程进行重构?

谢谢。

----后来补充------

我试图解决更广泛的问题是,我要开始一个AutoCAD应用,一些数据加载到它,然后让它运行我的客户与之交互。之后他会回到我的应用程序,我想重新连接到相同的AutoCAD会话并为其提供更多数据。

现在,我完全清楚地意识到,我可以将IDispatch指针保留在我的应用程序的内存中,并且可以继续与同一个AutoCAD进程交互。这是我的后备职位。

但是,我使用“包装”程序来做我的COM的东西。所以包装是暂时的。我的主应用程序启动包装,然后包装通信,然后退出。我只想让后续的包装进程能够重新连接到相同的AutoCAD进程。

为什么要使用包装?这是工作原因:我的主应用程序是32位应用程序,但我可以使用64位包装器并与64位AutoCAD通信。我需要能够与64位AutoCAD进行通信,并且可能无法轻松移植我的主应用程序(500K + C++行)与我的包装程序(几百行)。

+0

你试图解决什么更广泛的问题? – reuben 2009-09-03 06:41:46

+0

您应该使用SUCCEEDED()而不是!FAILED() - 这就是它的目的。我将编辑代码。 – sharptooth 2009-09-03 14:02:32

+0

在主帖中添加了“更广泛”的图片。 – 2009-09-03 17:58:19

回答

0

如果应用程序在运行对象表中注册了自己,则可以使用GetActiveObject函数来获取对应用程序对象的引用。

IUnknown *pUnknown; 

hr = GetActiveObject(clsid, NULL, &pUnknown); 
assert(SUCCEEDED(hr)); 

hr = pUnknown->QueryInterface(IID_IDispatch, (void **)&(iePtr_)); 
assert(SUCCEEDED(hr)); 
-1

不,这是不可能的。 COM的整个想法是,COM服务器是透明地启动的,只有在你停止使用它的对象之前才保持状态。在您释放COM对象后,COM子系统可以完全停止服务器,并且无法重新创建相同的进程。唯一可能的解决方法是使用带序列化方法的COM对象,该对象允许将状态保存到流中并从流中恢复。但即使如此,你将不得不再次使用CoCreateInstance(),获得一个新的COM对象接口指针并调用该对象的还原方法。

您从CoCreateInstance获得的指针仅对当前进程有效,如果将其保存在磁盘上并稍后恢复,则该指针将变为无效。

+0

这似乎是一个相当幼稚/最纯粹的COM观点 - 也许如果真正的COM代码只有这样的表现,世界才会更好。 – morechilli 2010-03-12 00:27:24

+0

@morechilli:这是模型暗示的行为。当然,这个实现的确如此。 – sharptooth 2010-03-12 06:13:41

0

CoMarshalInterface(和相关的API)可用于将接口编组到另一个线程,进程或网络上的不同PC上。我不知道在完成编组过程之前允许等待多长时间,但原则上,如果您编组接口的对象尚未关闭,则稍后可以完成编组过程。

能够销毁一个OLE对象,然后恢复“同一个对象”与所谓的Monikers绑定,如果你能够理解这些,那么你的OLE/COM Juju确实很强大。

+0

据称,DCOM有一个“垃圾回收”机制,在4分钟后杀死一个对象的存根,所以这是一个需要注意的超时。如果对象托管在自己的进程中,您应该能够将接口ptr编组到一个流中,将其写入磁盘,然后在另一个进程中重新构建,只要您在4分钟内完成。 – 2009-09-03 08:03:22

0

我建议让包装层长期存在而不是暂时的,因此它可以很容易地持有第三个应用程序的单一引用。

包装仍然可以对客户端代码显示为瞬态。 如果你使包装成为COM单体,那么每次你创建它时,你都会得到相同的实例。

为了确保包装器在您的客户端的生命周期中保持从启动到关闭的参考。此参考不需要连接到其他代码。所有其他代码只是在每次需要时创建单例。