繁体   English   中英

IConnectionPoint :: Advise从非主线程在Windows 10“ 1903”中不再起作用

[英]IConnectionPoint::Advise does not work any more in Windows 10 “1903” from the non-main thread

我们有一个应用程序,它可以在主线程中或在其他线程(异步)中运行一些COM宿主,并且我们想通过使用标准ConnectionPoint接口连接到该(可连接)对象以获得事件。

在Windows 10 SP 1903之前,它确实可以工作。

但是,当在“ 1903更新”中测试应用程序时,如果代码在与起始线程不同的线程中运行,则IConnectionPoint->Advise()因CONNECT_E_CANNOTCONNECT失败-在调用Advise()时,事件服务器会询问许多接口我不支持,我只应支持IUnknown,IDispatch和事件接口。

当整个事情都在非STA主线程中运行时,会查询很多接口,少于<1903,而在1903这些是:

clsEventSink(Dialog_)::QueryInterface(IID_IAgileObject) failed
clsEventSink(Dialog_)::QueryInterface({2132B005-C604-4354-85BD-8F2E24181B0C}) failed
clsEventSink(Dialog_)::QueryInterface(IID_IMarshal) failed
clsEventSink(Dialog_)::QueryInterface(IID_INoMarshal) failed
clsEventSink(Dialog_)::QueryInterface(IID_IAgileObject) failed
clsEventSink(Dialog_)::QueryInterface({2132B005-C604-4354-85BD-8F2E24181B0C}) failed
clsEventSink(Dialog_)::QueryInterface(IID_IMarshal) failed
clsEventSink(Dialog_)::QueryInterface({0000001B-0000-0000-C000-000000000046}) failed
clsEventSink(Dialog_)::QueryInterface(IID_IUnknown) succeeded
clsEventSink::AddRef(1)
clsEventSink::AddRef(2)
clsEventSink(Dialog_)::QueryInterface(IID_IStdMarshalInfo) failed
clsEventSink(Dialog_)::QueryInterface({334D391F-0E79-3B15-C9FF-EAC65DD07C42}) failed
clsEventSink(Dialog_)::QueryInterface({00000040-0000-0000-C000-000000000046}) failed
clsEventSink(Dialog_)::QueryInterface({334D391F-0E79-3B15-C9FF-EAC65DD07C42}) failed
clsEventSink(Dialog_)::QueryInterface(IID_IAgileObject) failed
clsEventSink(Dialog_)::QueryInterface({334D391F-0E79-3B15-C9FF-EAC65DD07C42}) failed
clsEventSink(Dialog_)::QueryInterface({77DD1250-139C-2BC3-BD95-900ACED61BE5}) failed
clsEventSink(Dialog_)::QueryInterface({334D391F-0E79-3B15-C9FF-EAC65DD07C42}) failed
clsEventSink(Dialog_)::QueryInterface({BFD60505-5A1F-4E41-88BA-A6FB07202DA9}) failed
clsEventSink(Dialog_)::QueryInterface({334D391F-0E79-3B15-C9FF-EAC65DD07C42}) failed
clsEventSink(Dialog_)::QueryInterface(IApplicationFrame) failed
clsEventSink(Dialog_)::QueryInterface(IApplicationFrameManager) failed
clsEventSink(Dialog_)::QueryInterface(IApplicationFrameEventHandler) failed
clsEventSink(Dialog_)::QueryInterface(IStreamGroup) failed
clsEventSink(Dialog_)::QueryInterface(iaudiodevicegraph) failed
clsEventSink(Dialog_)::QueryInterface({4F4F92B5-6DED-4E9B-A93F-013891B3A8B7}) failed
clsEventSink(Dialog_)::QueryInterface({9BC79C93-2289-4BB5-ABF4-3287FD9CAE39}) failed
clsEventSink(Dialog_)::QueryInterface({1868091E-AB5A-415F-A02F-5C4DD0CF901D}) failed
clsEventSink(Dialog_)::QueryInterface({11456F96-09D1-4909-8F36-4EB74E42B93E}) failed
clsEventSink(Dialog_)::QueryInterface(IEUserBroker) failed
clsEventSink(Dialog_)::QueryInterface({35BD3360-1B35-4927-BAE4-B10E70D99EFF}) failed
clsEventSink(Dialog_)::QueryInterface(IVerbStateTaskCallBack) failed
clsEventSink(Dialog_)::QueryInterface({334D391F-0E79-3B15-C9FF-EAC65DD07C42}) failed
clsEventSink(Dialog_)::QueryInterface({03FB5C57-D534-45F5-A1F4-D39556983875}) failed
clsEventSink(Dialog_)::QueryInterface({2C258AE7-50DC-49FF-9D1D-2ECB9A52CDD7}) failed
clsEventSink(Dialog_)::QueryInterface(IExternalConnection) failed
clsEventSink(Dialog_)::QueryInterface({4C1E39E1-E3E3-4296-AA86-EC938D896E92}) failed
clsEventSink(Dialog_)::QueryInterface({AF86E2E0-B12D-4C6A-9C5A-D7AA65101E90}) failed

Advise()然后放弃并返回上述错误代码。 因此,我无法在与应用程序主STA线程不同的线程中创建事件接收器。

更明确地说,我们有一个关系管理器应用程序,该应用程序希望在另一个线程中显示非模式对话框,即

  • 应用程序创建一个新线程,
  • 托管一个然后执行的脚本,
  • 脚本调用应用程序的方法(作为标准OLE服务器),该方法创建管理对话框窗口的OLE控件(使用CoCreateInstance等)[在我假设的主要STA线程中创建]
  • 然后脚本在脚本线程中连接控件(使用Advise()等),以便对话框控件可以使用脚本宿主中的对象触发事件

因此,如果要进行编组,那么我现在的猜测是它位于对话框控件内部,该控件必须对我传递给Advise()的指针进行编组,至少这是我在WWW的深度中所读到的内容。 因为我们在这里不做任何事情,它使用标准的编组器,所以通过combase!CStdMarshal:CreateStub()完成了编组(或至少尝试进行了编组),这似乎不再成功。 当我问一个接口(上面)时,堆栈是

>   cmSC24.dll!clsEventSink::QueryInterface(const _GUID & riid={...}, void * * ppv=0x04c5cf60) Line 121 C++
combase.dll!CStdMarshal::CreateStub(tagIPIDEntry * pEntry=0x0b87c388, IRpcStubBuffer * * ppStub=0x04c5d030, void * * ppv=0x04c5d034, int * pfNonNDR=0x04c5d038, IUnknown * pUnkUseInner=0x00000000) Line 6628   C++
[Inline Frame] combase.dll!CStdMarshal::ConnectSrvIPIDEntry(tagIPIDEntry *) Line 2600   C++
combase.dll!CStdMarshal::MarshalServerIPID(const _GUID & riid={...}, unsigned long cRefs=5, unsigned long mshlflags=0, tagIPIDEntry * * ppEntry=0x04c5d070, IUnknown * pUnkUseInner=0x00000000, PreventRundownBiasContainer * pBiasContainer=0x00000000, bool bApplyDirectMarshalingMitigation=false) Line 1539 C++
[Inline Frame] combase.dll!CStdMarshal::MarshalIPID(const _GUID &) Line 1391    C++
combase.dll!CRemoteUnknown::RemQueryInterface(const _GUID & ripid={...}, unsigned long cRefs=5, unsigned short cIids=1, _GUID * iids=0x0d7820fc, tagREMQIRESULT * * ppQIResults=0x04c5d4c8) Line 510    C++
rpcrt4.dll!_Invoke@12() Unknown
rpcrt4.dll!_NdrStubCall2@16()   Unknown
combase.dll!CStdStubBuffer_Invoke(IRpcStubBuffer * This=0x0e17f408, tagRPCOLEMESSAGE * prpcmsg=0x0e1e38b0, IRpcChannelBuffer * pRpcChannelBuffer=0x0e0bc540) Line 1531  C++
[Inline Frame] combase.dll!InvokeStubWithExceptionPolicyAndTracing::__l6::<lambda_ee1df801181086a03fa4f8f75bd5617f>::operator()() Line 1385 C++
combase.dll!ObjectMethodExceptionHandlingAction<<lambda_ee1df801181086a03fa4f8f75bd5617f> >(InvokeStubWithExceptionPolicyAndTracing::__l6::<lambda_ee1df801181086a03fa4f8f75bd5617f> action={...}, ObjectMethodExceptionHandlingInfo * pExceptionHandlingInfo=0x04c5d61c, ExceptionHandlingResult * pExceptionHandlingResult=0x04c5d600, void *) Line 87    C++
[Inline Frame] combase.dll!InvokeStubWithExceptionPolicyAndTracing(IRpcStubBuffer * pMsg=0x0e1e38b0, tagRPCOLEMESSAGE *) Line 1383  C++
combase.dll!DefaultStubInvoke(bool bIsAsyncBeginMethod=false, IServerCall * pServerCall=0x0dcc3f64, IRpcChannelBuffer * pChannel=0x0e0bc540, IRpcStubBuffer * pStub=0x0e17f408, unsigned long * pdwFault=0x04c5da08) Line 1452  C++
[Inline Frame] combase.dll!SyncStubCall::Invoke(IServerCall *) Line 1509    C++
[Inline Frame] combase.dll!SyncServerCall::StubInvoke(IRpcChannelBuffer *) Line 825 C++
[Inline Frame] combase.dll!StubInvoke(tagRPCOLEMESSAGE * pMsg=0x80004002, CStdIdentity * pStdID=0x0e2381e8, IRpcStubBuffer *) Line 1734 C++
combase.dll!ServerCall::ContextInvoke(tagRPCOLEMESSAGE * pMessage=0x0e1e38b0, IRpcStubBuffer * pStub=0x0e17f408, CServerChannel * pChannel=0x0e0bc540, tagIPIDEntry * pIPIDEntry=0x0d8e8d98, unsigned long * pdwFault=0x04c5da08) Line 1418 C++
[Inline Frame] combase.dll!CServerChannel::ContextInvoke(tagRPCOLEMESSAGE *) Line 1327  C++
[Inline Frame] combase.dll!DefaultInvokeInApartment(tagRPCOLEMESSAGE *) Line 3352   C++
combase.dll!ReentrantSTAInvokeInApartment(tagRPCOLEMESSAGE * pMsg=0x0e1e38b0, unsigned long dwCallCat=1, bool bIsTouchedASTACall=false, IRpcStubBuffer * pStub=0x0e17f408, CServerChannel * pChnl=0x0e0bc540, tagIPIDEntry * pIPIDEntry=0x0d8e8d98, unsigned long * pdwFault=0x04c5da08) Line 112   C++
combase.dll!AppInvoke(ServerCall * pServerCall=0x0dcc3f50, CServerChannel * pChannel=0x0e0bc540, IRpcStubBuffer * pStub=0x0e17f408, void * pStubBuffer=0x0d7820e0, void * pIPIDEntry=0x0d8e8d98, tagIPIDEntry * pLocalb=0x0d782080, WireLocalThis *) Line 1182  C++
combase.dll!ComInvokeWithLockAndIPID(ServerCall * pServerCall=0x0dcc3f50, tagIPIDEntry * pIPIDEntry=0x0d8e8d98, bool * pbCallerResponsibleForRequestMessageCleanup=0x04c5dc3f) Line 2290    C++
[Inline Frame] combase.dll!ComInvoke(ServerCall *) Line 1803    C++
[Inline Frame] combase.dll!ThreadDispatch(ServerCall *) Line 416    C++
combase.dll!ThreadWndProc(HWND__ * window=0x000707d2, unsigned int message=1024, unsigned int wparam=47806, long params=231489368) Line 744 C++
user32.dll!__InternalCallWinProc@20()   Unknown
user32.dll!UserCallWinProcCheckWow()    Unknown
user32.dll!DispatchMessageWorker()  Unknown
user32.dll!_DispatchMessageW@4()    Unknown
[Inline Frame] combase.dll!CCliModalLoop::MyDispatchMessage(tagMSG *) Line 3057 C++
combase.dll!CCliModalLoop::PeekRPCAndDDEMessage() Line 2693 C++
combase.dll!CCliModalLoop::FindMessage(unsigned long dwStatus=524296) Line 2764 C++
combase.dll!CCliModalLoop::HandleWakeForMsg() Line 2379 C++
combase.dll!CCliModalLoop::BlockFn(void * * ahEvent=0x04c5dfc0, unsigned long cEvents=1, unsigned long * lpdwSignaled=0x04c5dfa8) Line 2316 C++
combase.dll!ModalLoop(CSyncClientCall * pClientCall=0x0d74fc40) Line 166    C++
combase.dll!ClassicSTAThreadDispatchCrossApartmentCall(tagRPCOLEMESSAGE * pMessage=0x04c5e408, OXIDEntry * pOXIDEntry=0x0b87b5c0, CSyncClientCall * pClientCall=0x0d74fc40) Line 321    C++
[Inline Frame] combase.dll!CSyncClientCall::SwitchAptAndDispatchCall(tagRPCOLEMESSAGE * pMessage=0x04c5e408) Line 5696  C++
combase.dll!CSyncClientCall::SendReceive2(tagRPCOLEMESSAGE * pMessage=0x04c5e408, unsigned long * pstatus=0x04c5e3e4) Line 5377 C++
[Inline Frame] combase.dll!SyncClientCallRetryContext::SendReceiveWithRetry(tagRPCOLEMESSAGE *) Line 1617   C++
[Inline Frame] combase.dll!CSyncClientCall::SendReceiveInRetryContext(SyncClientCallRetryContext *) Line 567    C++
combase.dll!ClassicSTAThreadSendReceive(CSyncClientCall * pClientCall=0x0d74fc40, tagRPCOLEMESSAGE * pMsg=0x04c5e408, unsigned long * pulStatus=0x04c5e3e4) Line 549    C++
combase.dll!CSyncClientCall::SendReceive(tagRPCOLEMESSAGE * pMessage=0x04c5e408, unsigned long * pulStatus=0x04c5e3e4) Line 778 C++
[Inline Frame] combase.dll!CClientChannel::SendReceive(tagRPCOLEMESSAGE *) Line 653 C++
combase.dll!NdrExtpProxySendReceive(void * pThis=0x0e0703ec, _MIDL_STUB_MESSAGE * pStubMsg=0x04c5e4e8) Line 1998    C++
rpcrt4.dll!NdrClientCall2() Unknown
combase.dll!ObjectStublessClient(void * ParamAddress=0x04c5e910, long Method=5) Line 227    C++
combase.dll!_ObjectStubless@0() Line 171    Unknown
cmSC24.dll!clsEventSink::Connect(IUnknown * pUnknown=0x0e238d94, const String & sObject={...}, const String & sPrefix={...}, unsigned int * pnErrArg=0x04c5efa0, tagEXCEPINFO * pExepInfo=0x04c5efa4) Line 313  C++
cmSC24.dll!Connect(IUnknown * pUnknown=0x0e238d94, const String & sObject={...}, const String & sPrefix={...}, unsigned int * pnErrArg=0x04c5efa0, tagEXCEPINFO * pExepInfo=0x04c5efa4, clsScriptingHost * pHost=0x0e2f1fe8) Line 462   C++

我将其解释为试图设置默认编组的组合,但在1903年更新失败的地方。 所以我的问题是,为什么会失败?当我全部使用Advise()时,班级需要提供什么?

还是服务器(可连接对象)是在STA主线程中创建的,并且必须以某种方式进行更改以支持编组到新线程的调用Advise()的事件接收器中?

在以前的版本中几乎可以找到相同的堆栈,但是成功了。

嗯,很好-在对话框对象中使用VS 2019和_MERGE_PROXYSTUB(和一些调整)确实达到了目的……标准代理在这里可能是错误的,因此需要提供自己的代理吗? 哎呀,我很高兴它能奏效。

@Raymond:感谢您的回答-这是您引导我的正确曲目!

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM