重新连接到通过 COM 启动的进程

发布于 2024-08-03 20:57:49 字数 1095 浏览 6 评论 0原文

首先,我想指出,我需要使用 COM/OLE2 API、低级内容、可以放入 C Windows 控制台程序中的内容。我不会使用MFC。我无法使用.NET。

我的问题是:

给出以下代码:

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++)与我的包装程序(几百行)。

First, I'd like to note that I need to use the COM/OLE2 APIs, the low level stuff, the stuff you can put in a C Windows Console program. I can't use MFC. I can't use .NET.

My question is:

Given the following code:

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));

Is there a way to write some information to the disk so that I can reconnect to the same instance of IE later on? Basically can "iePtr_" be stringified for later reconstitution by some other process?

Thanks.

---- added later------

The broader problem I am trying to solve is that I want to start an AutoCAD application, load some data into it, and then leave it running for my client to interact with. Later he will go back to my application and I want to reconnect to the same AutoCAD session and feed it more data.

Now, I full well realize I can keep the IDispatch pointer in memory in my application and I'll be able to continue to interact with the same AutoCAD process. That's my fallback position.

However, I use a "wrapper" program to do my COM stuff. So the wrapper is transient. My main application starts the wrapper, then the wrapper communicates, and then exits. I just want subsequent wrapper processes to be able to reconnect to the same AutoCAD process.

Why use a wrapper? Here's the working reason: My main application is a 32-bit application, but I can use a 64-bit wrapper and communicate with 64-bit AutoCAD. I need to be able to communicate with 64-bit AutoCAD and can probably not port my main application easily (500K+ lines of C++) vs. my wrapper program (couple hundred lines).

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

岁月打碎记忆 2024-08-10 20:57:49

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

IUnknown *pUnknown;

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

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

If the application registered itself in the Running Object Table, you can use the GetActiveObject function to get a reference to the application object.

IUnknown *pUnknown;

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

hr = pUnknown->QueryInterface(IID_IDispatch, (void **)&(iePtr_));
assert(SUCCEEDED(hr));
满栀 2024-08-10 20:57:49

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

能够销毁 OLE 对象并随后恢复“同一对象”与所谓的名字相关联,如果您(可以)理解这些,那么您的 OLE/COM Juju 确实很强大。

CoMarshalInterface (and related APIs) can be used to marshal an interface into another thread, process or different PC on the network. I don't know how long you are allowed to wait before completing the marshaling process, but in principal, if the object you are marshaling an interface to has not been closed the marshaling process can be completed later.

Being able to destroy an OLE object and later restore "the same object" is tied into what are called Monikers, and if you (can) understand those then your OLE/COM Juju is powerful indeed.

耀眼的星火 2024-08-10 20:57:49

我建议使包装层长期存在而不是暂时存在,因此它可以轻松地保存对第三个应用程序的单个引用。

对于客户端代码来说,包装器仍然可能是暂时的。
如果您将包装器设为 COM 单例,那么每次共同创建它时,您都会获得相同的实例。

为了确保包装器在客户端的整个生命周期内都有效,请保留从启动到关闭的引用。该引用不需要连接到其他代码。所有其他代码只是在每次需要时创建单例。

I'd suggest making the wrapper layer long lived rather than transient, therefore it can easily hold a single reference to the third application.

The wrapper can still appear transient to the client code.
If you make the wrapper a COM singleton then each time you cocreate it, you will get back the same instance.

To ensure the wrapper lives for the lifetime of your client hold a reference from startup to shutdown. This reference does not need to be wired through to other code. All other code simply creates the singleton every time it wants it.

泅人 2024-08-10 20:57:49

不,那是不可能的。 COM 的整体思想是 COM 服务器透明地启动,并且仅保留状态,直到您停止使用其对象。释放 COM 对象后,COM 子系统可以完全停止服务器,并且无法重新创建相同的进程。获得类似结果的唯一方法是使用具有序列化方法的 COM 对象,该对象允许将状态保存到流中并从流中恢复状态。但即便如此,您也必须再次调用 CoCreateInstance(),获取新的 COM 对象接口指针并调用该对象的恢复方法。

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

Nope, that's impossible. The whole idea of COM is that the COM server is started transparently and only preserves state until you have stopped using its objects. After you've released the COM objects the COM subsystem is free to completely stop the server and there's no way to recreate the same process. The only way a similar result would be possible is to have a COM object with serialization methods that would permit saving the state into a stream and restoring it from a stream. But even then you would have to CoCreateInstance() again, obtain a new COM object interface pointer and call the restore method of that object.

The pointer you get from CoCreateInstance is only valid for the current process, if you save it on disk and restore later it will become invalid.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文