6

当客户端应用程序调用 c_com_ptr::CreateInstance (使用 ATL 包装器)时,我启动了一个 COM 服务器 LocalServer32 EXE。

在 Windows 7 上,当在同一用户帐户下运行的第二个客户端应用程序也调用 c_com_ptr::CreateInstance 时,将启动在同一用户帐户下运行的 EXE 的第二个副本。从前世我的印象是,第二个客户将共享第一个 EXE。

LocalServer32 进程是否共享?什么时候,什么时候不?谷歌搜索答案给我一个巨大的噪声信号比,我找不到答案。

我的 CLSID 注册表项的 LocalServer32 值给出了 EXE 路径、ProgID、可编程(空字符串)、TypeLib (GUID) 和 VersionIndependentProgId。我有一个 AppID 密钥。

不想将 EXE 作为服务运行,我不介意进程不共享。我只想知道规则,所以我知道会发生什么(在 Windows Server 2003 及更高版本上。)

编辑:在下面 Chris 的回答之后,我检查了我的服务器中的 CoRegisterClassObject 调用。我正在使用 ATL,并且我覆盖了 MyServer::RegisterClassObjects 以挂钩到 CAtlExeModuleT::RegisterClassObjects 的调用链,并看到 ATL 正在使用 CLSCTX_LOCAL_SERVER 和 REGCLS_MULTIPLEUSE。

将其更改为 CLSCTX_LOCAL_SERVER 和 REGCLS_SINGLEUSE 会导致启动更多进程,具体取决于客户端创建的 COM 对象的数量,如预期的那样。

尽管如此,回到 REGCLS_MULTIPLEUSE,每个 COM 客户端进程都有一个 COM 服务器进程,每个服务器进程都包含其客户端的所有 COM 对象,正如预期的那样,除了如果两个 COM 客户端在同一个用户帐户下运行,它们每个获得他们自己的服务器,这不是我理解的 REGCLS_MULTIPLEUSE。

不同之处在于客户端本身实际上是 Windows 服务吗?(它们是。)当作为用户帐户运行的 Windows 服务进程在 REGCLS_MULTIPLEUSE 下创建一个 COM 对象时,是否会进行不同的处理,从而导致观察到的行为?为什么我得到多个进程?(澄清一下,我希望我的 COM 服务器作为 Windows 服务运行,但使用它的客户端确实作为 Windows 服务运行。)

此外,将客户端作为本地系统或网络服务运行,REGCLS_MULTIPLEUSE 可以正常工作:只启动一个 COM 服务器 EXE 进程。当 COM 客户端是在用户帐户下运行的 Windows 服务时,将启动多个进程。

4

1 回答 1

7

进程外激活请求的路由由向 COM 服务控制管理器注册的类对象控制。如果 SCM 有一个可用的注册类对象,它将用于为请求提供服务。如果没有,它将启动 COM 服务器的一个 exe 进程实例来获取一个。因此,多个激活请求是否路由到单个 COM 服务器 exe 进程至少取决于以下因素(我不确定这是否是完整列表):

  • COM 服务器在调用 CoRegisterClassObject 向 SCM 注册时指定的激活标志可能会导致未来的激活请求导致启动新的 exe 进程实例,最简单和最常见的情况是使用标志 REGCLS_SINGLEUSE,它允许注册的仅用于单个激活的类对象。
  • 根据类的注册方式,来自不同安全上下文的激活请求可能由不同的 COM 服务器 exe 实例提供服务(这似乎不适用于您的场景,因为您的客户端应用程序在相同的安全上下文下运行)。
于 2011-02-24T12:46:19.907 回答