2

我有一个用 C++ 编写的 ATL exe 服务器(Visual Studio 2010,合并了 proxy-stud dll)。该可执行文件针对 Windows 7 x86 和 x64 编译。两种架构都会发生以下情况:

ATL exe 服务器应该充当“服务器进程”,也就是说 - 每台机器应该存在一个进程(MyATLServer.exe,只有一个!),并且许多客户端(让我们保持简单:在同一台机器上)正在使用来自的 COM 对象它。服务器保存应用程序状态(在内存中),所有客户端都应该通过使用服务器公开的 COM 对象来“共享”这个状态。

exe 服务器通常在系统启动时启动,因为它是由 COM 调用调用以创建它的托管对象之一。该调用源自 spoolsv.exe 进程(打印后台处理程序服务)。这会导致服务器进程在“SYSTEM”用户下运行(我猜是因为 spoolsv.exe 使用“SYSTEM”运行)。

当其中一个客户端从 ATL 服务器创建 COM 对象时,另一个进程(又是 MyATLServer.exe)被实例化(在登录到 Windows 的用户下运行),因此,它不能与“原始”进程共享应用程序状态(它在'SYSTEM'下运行)。第二个客户端将连接到由登录用户实例化的那个(“第二个”)。

在网上搜索了无数论坛后,我设法得出以下结论:

1) 我的 ATL 服务器使用默认的(由 VS2010 自动生成的)ATL-Module,它继承自 ATL::CAtlExeModuleT<>。深入研究 ATL 标头,我确信该模块调用 AtlComModuleRegisterClassObjects 时使用了正确的标志(dwClsContext = CLSCTX_LOCAL_SERVER,标志 = REGCLS_MULTIPLEUSE | REGCLS_SUSPENDED)。所以它排除了这个。

2) 使用 start -> run -> dcomcnfg -> DCOM Config -> MyATLServer -> Properties 我在“身份”选项卡下设置了“此用户”选项(使用本地管理员用户)。在“位置”选项卡中,未选中“在此计算机上运行应用程序”选项并显示为灰色。这让我再次搜索,我到了这里:http ://social.technet.microsoft.com/Forums/en-US/w7itprosecurity/thread/4f63ee11-e472-40f9-85db-a6b235d7579c 。该链接说明 dcomcnfg 实用程序的 x64 版本存在错误,应该在 x64 Windows 上使用它的 32 位版本(开始->运行->'mmc comexp.msc /32')。在两个系统(每个系统一个)上检查后,我发现“在这台计算机上运行应用程序”选项显示为灰色,并且在两个系统上都没有选中。

从这一点开始,我完全迷失了(并试图抑制挫败感...... :-))。我在正确的道路上吗?以前有人这样做过吗?

或最初的意图 - 如何使我的 ATL exe 服务器“单处理”?

谢谢!

暗里

4

1 回答 1

2

好的......所以最后我要回答自己:-)

我找到了一些时间再次尝试解决这个问题(一次又一次......)。在设置了 2 台不同的新开发机器(Win7x86 和 Win7x64)并仅使用 32 位版本的 dcomcnfg 之后 - 一台机器工作,一台 32 位的机器(Win7x86)!

深入研究“非工作”机器,我发现我遇到了 GUID 地狱!在 x64 开发机器上,COM 对象注册的 GUID 与代码文件(生成代码)中的值不同。更困难的是,我使用了连接点,这些连接点也注册了无效的 GUID。我的意思是 - 注册表中的 GUID 值不正确!到目前为止,我不知道为什么会发生这种情况,但我 100% 确定 VS2010 中的 COM 向导存在错误(生成部分代码,如果有的话......),也许这些向导生成的代码导致注册问题。

为了解决这个问题,我手动删除了 ATL 服务器的所有相关注册表项,取消了 VS 项目中的自动 COM 注册并自己注册了 EXE(在 x64 上使用 %WINDIR%\SysWOW64\cmd.exe 控制台,不是本机 x64 之一)。

手动注册服务器后,一切正常(正如预期的那样,一个进程,在多个客户端之间共享),并且 dcomcnfg 配置实用程序中没有灰色的复选框。

我确信这个解决方案有很多无法解释的差距,但它对我有用(现在......)。

干杯;-)

于 2011-04-18T11:14:12.273 回答