如何为进程外COM服务器强制进程隔离?

时间:2022-11-14 09:02:26

I'm writing managed code that has to interact with a vendor's COM automation server that runs out of process. I have found that this server becomes unstable if more than one client connects to it. For example, if I have managed code in process A and managed code in process B both connecting to this COM server, a single process will be spun up for the COM server and it's behavior is less than reliable. I'm hoping there's a way to force a separate process for each client - server connection. Ideally, I'd like to end up with:

我正在编写托管代码,必须与供应商的COM自动化服务器进行交互。我发现如果多个客户端连接到它,该服务器就会变得不稳定。例如,如果我在进程A中的托管代码和进程B中的托管代码都连接到此COM服务器,则将为COM服务器启动单个进程,并且它的行为不太可靠。我希望有一种方法可以为每个客户端强制一个单独的进程 - 服务器连接。理想情况下,我最终会:

Managed Process A talking to COM Server in process C1
Managed Process B talking to COM Server in process C2

托管进程A在进程C1中与COM服务器通信管理进程B在进程C2中与COM服务器通信

One thought that came to mind was that if I ran process A and process B with different security identities, that that might cause the COM infrastructure to create separate server processes. I'd rather not go down that road, however. Managed Process A and Managed Process B are actually Windows Services. And I'm running them with identity Local System (because I need them to be able to interact with the desktop, and you can't check the "Interact with Desktop" box on the services applet for services that don't run as Local System). And the reason I need to interact with desktop is that this COM server occasionally throws up a dialog box on the screen and if the service itself cannot interact with the desktop then the COM server is spawns can't display the dialog (I believe it is displayed on a hidden WinStation).

我想到的一个想法是,如果我使用不同的安全标识运行进程A和进程B,那可能会导致COM基础结构创建单独的服务器进程。但是,我宁愿不去那条路。托管进程A和托管进程B实际上是Windows服务。我正在使用身份本地系统运行它们(因为我需要它们能够与桌面交互,并且您无法检查服务小程序上的“与桌面交互”框,以获取不作为本地运行的服务系统)。我需要与桌面交互的原因是这个COM服务器偶尔会在屏幕上抛出一个对话框,如果服务本身无法与桌面交互,那么COM服务器就会产生无法显示对话框(我相信它是显示在隐藏的WinStation上)。

3 个解决方案

#1


Place the component registered at COM+, this put an isolation layer at your.
Use : Control Panel->Administrative Tools
or cmd/execute DCOMCNFG

将组件注册到COM +,这会在您的隔离层上放置一个隔离层。使用:控制面板 - >管理工具或cmd /执行DCOMCNFG

Component Services->Computers->My Computer->COM+ Application, right click, new application, next, Create an empty application, enter app name “COM+ your.dll”, next, select Local Service, next, next, next, finish.

组件服务 - >计算机 - >我的电脑 - > COM +应用程序,右键单击,新建应用程序,下一步,创建一个空应用程序,输入应用程序名称“COM + your.dll”,然后选择本地服务,下一步,下一步,下一步,完成。

In new item made, expand, at Components, right click, new component, next, select Install new component, select your component.

在新项目中,展开,在组件中,右键单击,新组件,然后选择安装新组件,选择您的组件。

Click Component properties, tab Identity, select System Account.

单击组件属性,选项卡标识,选择系统帐户。

For errors in calls see Event after.

对于调用中的错误,请参阅事件后。

#2


It's been a while since I've done this, so my memory is hazy.

我已经有一段时间了,所以我的记忆是模糊的。

If you configure the OOP COM server as a DCOM server using the DCOM config tool, I believe you can specify the isolation level. I did this years ago with a non-threadsafe in-process DLL that needed to be accessed in a threadsafe fashion from IIS and it worked a charm.

如果使用DCOM配置工具将OOP COM服务器配置为DCOM服务器,我相信您可以指定隔离级别。我在几年前做了一个非线程安全的进程内DLL,需要以线程安全的方式从IIS访问它并且它起了作用。

Let me know if it works for you :)

请让我知道这对你有没有用 :)

#3


Your best bet would be to get the vendor to fix the component. After all, if it won't handle multiple clients, there could be other bugs lurking. If you can't do this, there are some other things to try.

您最好的选择是让供应商修复该组件。毕竟,如果它不能处理多个客户端,可能会有潜伏的其他错误。如果你不能这样做,还有其他一些事情要尝试。

With in-process COM objects I've had occassion to manually load the dll and access the interfaces directly without going through COM.

使用进程内COM对象,我已经有了手动加载dll并直接访问接口而无需通过COM。

I haven't done this myself with out-of-process COM, but there are some things you could try. Ultimately the library is just a process sitting there receiving messages which invoke functions.

我自己没有使用进程外COM,但有些事情你可以尝试。最终,库只是一个坐在那里接收调用函数的消息的过程。

You might be able to manually start the a new copy of the process for each client and then send it messages. You may run into some hiccups with this. For example, the process may check to see if it's already running and refuse to start or otherwise be unhappy.

您可以为每个客户端手动启动进程的新副本,然后向其发送消息。你可能会遇到一些打嗝。例如,该过程可以检查它是否已经在运行并且拒绝启动或者不满意。

If you have a known upper limit on the number of clients, another approach you could consider would be to make multiple copies of the original .exe file and then use binary patching (something similar to the detours library from Microsoft Research) to override the COM registration functions and register each copy as a separate COM object.

如果您有一个已知的客户端数量上限,您可以考虑的另一种方法是制作原始.exe文件的多个副本,然后使用二进制修补(类似于Microsoft Research的detours库)来覆盖COM注册函数并将每个副本注册为单独的COM对象。

#1


Place the component registered at COM+, this put an isolation layer at your.
Use : Control Panel->Administrative Tools
or cmd/execute DCOMCNFG

将组件注册到COM +,这会在您的隔离层上放置一个隔离层。使用:控制面板 - >管理工具或cmd /执行DCOMCNFG

Component Services->Computers->My Computer->COM+ Application, right click, new application, next, Create an empty application, enter app name “COM+ your.dll”, next, select Local Service, next, next, next, finish.

组件服务 - >计算机 - >我的电脑 - > COM +应用程序,右键单击,新建应用程序,下一步,创建一个空应用程序,输入应用程序名称“COM + your.dll”,然后选择本地服务,下一步,下一步,下一步,完成。

In new item made, expand, at Components, right click, new component, next, select Install new component, select your component.

在新项目中,展开,在组件中,右键单击,新组件,然后选择安装新组件,选择您的组件。

Click Component properties, tab Identity, select System Account.

单击组件属性,选项卡标识,选择系统帐户。

For errors in calls see Event after.

对于调用中的错误,请参阅事件后。

#2


It's been a while since I've done this, so my memory is hazy.

我已经有一段时间了,所以我的记忆是模糊的。

If you configure the OOP COM server as a DCOM server using the DCOM config tool, I believe you can specify the isolation level. I did this years ago with a non-threadsafe in-process DLL that needed to be accessed in a threadsafe fashion from IIS and it worked a charm.

如果使用DCOM配置工具将OOP COM服务器配置为DCOM服务器,我相信您可以指定隔离级别。我在几年前做了一个非线程安全的进程内DLL,需要以线程安全的方式从IIS访问它并且它起了作用。

Let me know if it works for you :)

请让我知道这对你有没有用 :)

#3


Your best bet would be to get the vendor to fix the component. After all, if it won't handle multiple clients, there could be other bugs lurking. If you can't do this, there are some other things to try.

您最好的选择是让供应商修复该组件。毕竟,如果它不能处理多个客户端,可能会有潜伏的其他错误。如果你不能这样做,还有其他一些事情要尝试。

With in-process COM objects I've had occassion to manually load the dll and access the interfaces directly without going through COM.

使用进程内COM对象,我已经有了手动加载dll并直接访问接口而无需通过COM。

I haven't done this myself with out-of-process COM, but there are some things you could try. Ultimately the library is just a process sitting there receiving messages which invoke functions.

我自己没有使用进程外COM,但有些事情你可以尝试。最终,库只是一个坐在那里接收调用函数的消息的过程。

You might be able to manually start the a new copy of the process for each client and then send it messages. You may run into some hiccups with this. For example, the process may check to see if it's already running and refuse to start or otherwise be unhappy.

您可以为每个客户端手动启动进程的新副本,然后向其发送消息。你可能会遇到一些打嗝。例如,该过程可以检查它是否已经在运行并且拒绝启动或者不满意。

If you have a known upper limit on the number of clients, another approach you could consider would be to make multiple copies of the original .exe file and then use binary patching (something similar to the detours library from Microsoft Research) to override the COM registration functions and register each copy as a separate COM object.

如果您有一个已知的客户端数量上限,您可以考虑的另一种方法是制作原始.exe文件的多个副本,然后使用二进制修补(类似于Microsoft Research的detours库)来覆盖COM注册函数并将每个副本注册为单独的COM对象。