events - 如何在未注册的 COM 服务器中使用事件
问题描述
对于开发,我使用 EXE 文件中包含的进程外 COM 服务器而不注册它。只要客户端只使用后期绑定,并且我在启动一个客户端之前启动服务器 EXE,这就可以正常工作。(服务器注册一个类工厂,然后由客户端使用。)
我知道这是一个 hack,而且我知道这可能会在任何操作系统组件的下一次更新中停止工作。我这样做只是为了开发,而不是为了测试,绝对不是为了与生产相关的任何事情。
但是,使用事件不起作用:客户端在调用时报告 CONNECT_E_CANNOTCONNECT IConnectionPoint.Advise
,即“订阅”事件时。
我怎样才能使这项工作?
一些细节:
我有一个
IFooEvents
GUID接口{111blah...}
,客户端(根据 Procmon)尝试查找HKCR\Interfaces\{111blah...}
。如果此密钥存在,它将包含:[HKEY_CLASSES_ROOT\Interface\{111blah...}] @="IFooEvents" [HKEY_CLASSES_ROOT\Interface\{111blah...}\ProxyStubClsid32] @="{00020420-0000-0000-C000-000000000046}" <-- PSDispatch? [HKEY_CLASSES_ROOT\Interface\{111blah...}\TypeLib] @="{GUID of the server assembly}" "Version"="1.0"
这里有什么相关的?是吗
PSDispatch
,如果是的话,有没有办法可以在运行时提供这些信息?
我的测试客户端恰好是 .NET,并用于dynamic
确保使用后期绑定。
堆栈跟踪:
System.Runtime.InteropServices.COMException: 'No such interface supported at System.Runtime.InteropServices.ComTypes.IConnectionPoint.Advise(Object pUnkSink, Int32& pdwCookie) at System.Dynamic.ComEventSink.Initialize(Object rcw, Guid sourceIid) at System.Dynamic.ComEventSink..ctor(Object rcw, Guid sourceIid) at System.Dynamic.ComEventSink.FromRuntimeCallableWrapper(Object rcw, Guid sourceIid, Boolean createIfNotFound) at System.Dynamic.BoundDispEvent.InPlaceAdd(Object handler) at System.Dynamic.BoundDispEvent.TryBinaryOperation(BinaryOperationBinder binder, Object handler, Object& result) at CallSite.Target(Closure , CallSite , Object , SomethingHappenedEventHandler ) at System.Dynamic.UpdateDelegates.UpdateAndExecute2[T0,T1,TRet](CallSite site, T0 arg0, T1 arg1) at Program.Main()
.NET 框架单步执行失败,VS 报告它找不到
Binder.cs
,我无法单步执行代码。此外,我在堆栈跟踪中找不到任何代码的来源。为了完整起见:注册 COM 服务器 EXE 文件后一切正常。
如果不可能,我很高兴知道原因,只是为了了解更多关于 COM 的信息。
解决方案
推荐阅读
- windows - 将组策略明确定义为“No One”——有风险吗?
- python - 如何在python的数组中获取特定数字的坐标?
- reactjs - 使用 Sinon 存根 React useState
- c++ - 为什么文件名会影响 C++ 中的结构?
- node.js - 正则表达式替换值
- audiokit - 一起使用 AKNodeOutputPlot 和 AKNodeRecorder 时崩溃
- informix - 如何从给定的日期时间获取一天结束
- python - 我从上一个问题中找到的用于连接 CSV 文件的细分代码?
- java - 想要在 App 中以编程方式删除文件
- php - Windows/temp 文件夹中的 Phpxxxx.tmp 文件没有被删除