COM对象从一个程序实例化,而不是从在同一用户下运行的另一个程序实例化

本文关键字:实例化 程序 用户 运行 另一个 对象 一个 COM | 更新日期: 2023-09-27 18:02:03

我们的COM组件遇到了一个相当奇怪的问题。该组件实现了一个众所周知的接口,并被第三方闭源产品(以下简称产品X)使用。产品X通过Windows注册表配置-产品X读取注册表并找到我们组件的类id。

我们的组件是在本地c++中使用ATL实现的32位进程内组件,我们在64位系统上用COM+注册它,以便它在代理进程中被激活。

现在产品X无法使用我们的组件并在Windows事件日志中跟踪E_ACCESSDENIED,我们还看到以下错误消息

特定于应用程序的权限设置不授予具有CLSID {COM对象的class id}和APPID {COM+应用程序的app id}的COM服务器应用程序的本地激活权限给用户MACHINENAME'管理员SID(这里的SID)从地址LocalHost(使用LRPC)。此安全权限可以使用组件服务管理工具进行修改。

in system log.

这看起来像是权限问题。因此,我们用c#编写了一个"Hello, world"程序,其中new是一个COM组件,并从中调用一个简单的(从不失败的)方法:

OurComponent。IOurComponent component = new OurComponent.OurcomponentClass();

component.TrivialMethod ();

当该程序从与产品X相同的帐户运行时,它可以正常工作-组件被实例化,我们甚至可以在COM+控制台中看到"带加号的绿球"旋转。

所以我们有两个程序在同一台机器上以相同的用户帐户运行,一个可以实例化COM组件,另一个不能。原因是什么呢?

COM对象从一个程序实例化,而不是从在同一用户下运行的另一个程序实例化

我认为你缺少应用程序的配置。

有两个条件。你的应用程序需要编译为"Com可见"。你需要注册com组件(如果还没有注册)

进入开始->管理工具->组件服务。展开组件服务,计算机,我的计算机,DCOM配置。向下滚动并找到应用程序。右击->单击->属性并选择安全选项卡。您将在这里看到一些选项-第一个块启动和激活权限-确保自定义单选按钮被选中,然后单击编辑。现在,给你正在使用的帐户启动,激活,以及远程启动/激活权限。重新启动机器(或重新启动服务/应用程序),希望它能工作。