TL; DR -如何防止-Embedding
服务器CLSCTX_LOCAL_SERVER
的启动?最好让客户立即获得体面的错误代码。
我们有一个本机C ++交互式桌面应用程序,该应用程序与另一个本机C ++交互式桌面应用程序中的COM对象进行交互。
基本上,COM被用作进程间通信机制。
现在,当用户将其进入正确状态后以交互方式启动“服务器”应用程序时,它将准备COM接口:CoRegisterClassObject
等。
使用客户端应用程序,然后对协类使用CoCreateInstance
时,它将与已经运行的其他桌面应用程序进行通信,这就是预期的目的。
但是,当“服务器”应用程序未运行时,启动客户端将以交互方式启动服务器应用程序,这不是我们想要的,因为在客户端进行有意义的通信之前,它需要进行大量的处理和设置。
因此,更有意义的是,在服务器未运行的情况下,客户端只是出错,而不是让COM基础结构启动一个交互式应用程序,该应用程序无论如何都无法有效地为请求提供服务。
我们玩弄了以下想法:
CLSCTX_DISABLE_AAA
标志。
0x80070005 ERROR_ACCESS_DENIED
,但我们不确定这是否正确。-Embedding
开关,然后立即退出此应用程序。
CoRegisterClassObject
should be enough。
HKCR\AppID (...)
HKCR\CLSID\{...}
加上子键ProgID
,VersionIndependentProgID
,LocalServer32
,Typelib
对于给定的注册COM类,是否有任何“标准”方法来阻止COM本地服务器可执行文件激活?
答案 0 :(得分:1)
我的想法是这个...
当您检测到服务器以-Embedding启动时,只需在EXE中设置全局标志即可。我可能只有在使用-Embedding标志启动时才创建特殊类工厂。调用IClassFactory :: CreateInstance()时,此类工厂将返回失败代码。您不会将标准类工厂注册为与CoRegisterClassObject()一起运行,而是仅注册始终返回失败代码的替代工厂。
是的,在启动EXE时仍然会稍有延迟,但是当调用CreateInstance()时,它将立即返回失败代码,因此调用方将不会有很长的超时时间...也许是1-仅5秒。
答案 1 :(得分:-1)
总结我到目前为止从评论中学到的东西:
您不必使用CoCreateInstance
,但是您可以使用GetActiveObject
,
检索指向已使用OLE注册的运行对象的指针。
因此,您有一种获取对象的方法,而无需激活它,而是依靠它已经被注册。 (但这不是CoRegosterClassObject
完成的,您需要...?)
类似于GetActiveObject
的方法,您可以使用IRunningObjectTable
周围的机器-无论如何,这可能是GetActiveObject在幕后使用的。我在那儿迷路了。
另一条信息是registry is claimed to be kinda "optional"的所有含义:(解释)
CoRegisterClassObject
仅用于将对象发布到COM(作为oop服务器), ...只需不在注册表中注册对象
CLSID
。 如果服务器尚未调用CoRegisterClassObject
,则客户端将收到错误REGDB_E_CLASSNOTREG
,否则调用CoRegisterClassObject
就足够了。 ...您不需要将其添加到“运行对象表”中-单个调用
CoRegisterClassObject
就足够了-客户端可以在此之后创建实例。无需在注册表中进行任何注册-......对于任何远程接口,您当然都需要注册表
Interface\{..}\ProxyStubClsid32
中的一个条目,但对于CLSID
,不需要。
CoRegisterClassObject
完全不需要注册表... 但是,您仍然需要编组您的界面。为此,您需要Interface\{..}\ProxyStubClsid32
键。如果进行这种封送处理,则需要
TypeLib
-在此处设置{00020424-0000-0000-C000-000000000046}。您不需要的CLSID
和AppID
。
CLSID
和APPID
,如果尚未启动(或加载dll),则需要启动它。如果您已经在运行并致电
CoRegisterClassObject
-这足以使客户端呼叫连接到您。 但是,如果没有CLSID,客户端将无法执行您的应用程序(根本不知道是什么)。如果您不进行自定义封送处理-每个接口都需要在注册表中包含信息-哪个dll ProxyStubClsid32可以进行此封送处理。这可以是自定义dll,也可以是自定义dll,或者如果是标准{00020424-0000-0000-C000-000000000046},则需要供oleaut32使用的typelib。
在摘要中,看来阻止Windows启动应用的方法是
CoCreateInstance
并通过另一条路线检索对象。