c++ - CoCreateInstance 不启动或连接到 ATL COM 服务

标签 c++ visual-studio-2010 com windows-services atl

我有一个 ATL COM 服务 exe (MyService.exe),它编译并运行良好。如果我安装此服务(通过 MyService.exe/Service),它会成功安装到 SCM 中。我可以通过 SCM 启动该服务,它在 LOCALSYSTEM 帐户下运行良好。

当我尝试创建由服务定义的 COM 类的实例时,我的问题出现了。我的测试工具应用程序 (MyServiceTest.exe) 调用以下内容:

::CoInitialize(NULL);
::CoInitializeSecurity(NULL, 
                        NULL, 
                        NULL, 
                        NULL, 
                        RPC_C_AUTHN_LEVEL_PKT, 
                        RPC_C_IMP_LEVEL_IMPERSONATE, 
                        NULL, 
                        EOAC_NONE, 
                        NULL);
ATL::CComPtr<IMyServiceInterface> pInterface;
HRESULT hr = CoCreateInstance(CLSID_MyServiceInterface, NULL, CLSCTX_LOCAL_SERVER, IID_IMyServiceInterface, reinterpret_cast<void**>(&pInterface));

在调用 CoCreateInstance 时,会发生一些不同的事情,具体取决于 MyService.exe 的安装方式:

  1. MyService.exe 使用/Service 命令行安装:
    MyServiceTest.exe 调用 CoCreateInstance,并调用 MyService WinMain。然后调用 CAtlServiceModuleT::Start,确定可执行文件已使用命令行选项“-Embedding”启动。它确定它是作为服务安装的,因此调用::StartServiceCtrlDispatcher()。此调用失败,错误代码为 1063 (ERROR_FAILED_SERVICE_CONTROLLER_CONNECT)。根据 MS:

"This error is returned if the program is being run as a console application rather than as a service. If the program will be run as a console application for debugging purposes, structure it such that service-specific code is not called when this error is returned."

调用失败,MyService.exe 退出,CoCreateInstance 调用超时。

  1. MyService.exe 不是作为服务安装的,而是通过/RegServer 注册的
    MyServiceTest.exe 调用 CoCreateInstance,并调用 MyService WinMain。 MyService.exe 在登录用户帐户(不是 LOCALSYSTEM)下实例化。可执行文件成功运行,但不是作为服务运行,这不是所需的行为。尽管没有作为服务运行,CoCreateInstance() 调用还是成功了,并且我获得了一个有效的接口(interface)指针,通过它我可以调用 MyService COM 函数。

  2. MyService.exe 未作为服务安装,通过/RegServer 注册,并且已经在运行(例如在场景 2 中成功启动后)
    MyServiceTest.exe 调用 CoCreateInstance,MyService.exe 的一个新实例被实例化,再次在登录用户帐户下。对于 CoCreateInstance 的每个后续调用,此行为都会继续。

我希望的行为是我可以将 MyService.exe 作为服务安装,CoCreateInstance 将启动服务器,或者如果该服务已经在运行,则连接到当前的 MyService.exe 实例。据我所知,上面的代码应该以这种方式运行。我错过了什么?

服务在 LOCALSYSTEM 下运行,而简单的 RegServer 替代方案在本地用户下运行似乎是相关的,但我不确定这是否是问题所在。

服务端对 CoInitializeSecurity 的调用是:

HRESULT hr = CoInitializeSecurity(0,
                                    -1,
                                    0,
                                    0,
                                    RPC_C_AUTHN_LEVEL_PKT,
                                    RPC_C_IMP_LEVEL_IMPERSONATE,
                                    0,
                                    EOAC_NONE,
                                    0);

我做错了什么?

附言MyService.exe 不应在启动后退出,因为它在 Run() 函数中包含一个等待外部信号的 WaitForSingleObject()(该信号也在 OnStop() 中设置,以便 SCM 可以停止服务)。这就是 MyService.exe 在 MyServiceTest.exe 完成后仍然存在的原因。这是期望的行为(对于服务,这是它应该运行的样子)。

最佳答案

如果您已经了解了这一点,请原谅我:

运行 DCOMCNFG.EXE。

向下钻取组件服务\计算机\我的电脑\DCOM 配置。

找到您的组件,右键单击并激活“属性”。

在“标识”选项卡中,确保将 COM 组件配置为在运行服务的同一标识下运行。

关于c++ - CoCreateInstance 不启动或连接到 ATL COM 服务,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5813681/

相关文章:

visual-studio - TFS2010 : Fast way to determine user, 谁编辑了 "this function"或 "this line of code"?

c# - VS 2010 调试 - 可视化工具在哪里

com - 手动注册activex exe

c# - Excel COM 互操作 - 为什么返回类型通常是动态的?

c# - 使用 COM 二进制序列化作为 C# 和 C++ 不可抗拒的格式

c++ - 在网页上托管 C++ 桌面应用程序

用于指定任何无符号整数类型的 C++ 模板特征

c++ - Google Chrome浏览器在访问网站时发送第二个长度为0的请求吗?

c# - 如何用Mono/C#程序调用linux/c++函数?

visual-studio-2010 - 将菜单按钮添加到 VS2010 TFS 查询结果或工作项栏