简体   繁体   English

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

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

We have an application that either runs some COM hosting in the main thread or in a different thread (async), and we would like to connect to this (connectable) object by using the standard ConnectionPoint interfaces in order to get its events. 我们有一个应用程序,它可以在主线程中或在其他线程(异步)中运行一些COM宿主,并且我们想通过使用标准ConnectionPoint接口连接到该(可连接)对象以获得事件。

Up to Windows 10 SP 1903, it did work. 在Windows 10 SP 1903之前,它确实可以工作。

But when testing the application in the "1903 update" the IConnectionPoint->Advise() fails with CONNECT_E_CANNOTCONNECT when the code is run in a different thread than the starting thread - while Advise() is called, the event server asks a lot of interfaces I do not support, I only support IUnknown, IDispatch and the event interface as should be. 但是,当在“ 1903更新”中测试应用程序时,如果代码在与起始线程不同的线程中运行,则IConnectionPoint->Advise()因CONNECT_E_CANNOTCONNECT失败-在调用Advise()时,事件服务器会询问许多接口我不支持,我只应支持IUnknown,IDispatch和事件接口。

There are a lot of interfaces queried when the whole thing is run in the non-STA main thread, less in < 1903, and in 1903 these are: 当整个事情都在非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() is then giving up and returning the error code mentioned above. Advise()然后放弃并返回上述错误代码。 Thus I cannot create an event sink any more in a different thread than the application' main STA thread. 因此,我无法在与应用程序主STA线程不同的线程中创建事件接收器。

More explicitly, we have a relationship manager application that wants to show a nonmodal dialog in a different thread, ie 更明确地说,我们有一个关系管理器应用程序,该应用程序希望在另一个线程中显示非模式对话框,即

  • the application creates a new thread, which 应用程序创建一个新线程,
  • hosts a script that is then executed, 托管一个然后执行的脚本,
  • the script calls a method of the application (being a standard OLE server) which creates the OLE control managing the dialog window (using CoCreateInstance etc) [created in the main STA thread I assume] 脚本调用应用程序的方法(作为标准OLE服务器),该方法创建管理对话框窗口的OLE控件(使用CoCreateInstance等)[在我假设的主要STA线程中创建]
  • and then the script connects the control (using the Advise() etc) in the script's thread so that the dialog control can fire events using an object in the scripting host 然后脚本在脚本线程中连接控件(使用Advise()等),以便对话框控件可以使用脚本宿主中的对象触发事件

So if there's marshalling to do, my guess now is that it is inside the dialog control which must marshal the pointer I pass to Advise(), at least that's what I read in the depth of the WWW. 因此,如果要进行编组,那么我现在的猜测是它位于对话框控件内部,该控件必须对我传递给Advise()的指针进行编组,至少这是我在WWW的深度中所读到的内容。 As we do not do anything here, it uses a standard marshaller, the marshalling is being done (or at least tried to do) by combase!CStdMarshal:CreateStub() which seemingly does not succeed any more. 因为我们在这里不做任何事情,它使用标准的编组器,所以通过combase!CStdMarshal:CreateStub()完成了编组(或至少尝试进行了编组),这似乎不再成功。 The stack when I'm asked for one the interfaces (above) is 当我问一个接口(上面)时,堆栈是

>   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++

which I interprete as combase trying to set up a default marshalling, and somewhere failing in the 1903 update. 我将其解释为试图设置默认编组的组合,但在1903年更新失败的地方。 So my question is, why could it be failing, and what does my class need to supply when I all Advise()? 所以我的问题是,为什么会失败?当我全部使用Advise()时,班级需要提供什么?

Or is it that the server (connectable object) is created in the STA main thread and must be changed somehow to support the marshalling into the new thread's event sink calling Advise()? 还是服务器(可连接对象)是在STA主线程中创建的,并且必须以某种方式进行更改以支持编组到新线程的调用Advise()的事件接收器中?

Nearly the same stack is found in previous versions, but it succeeded. 在以前的版本中几乎可以找到相同的堆栈,但是成功了。

Ah, well - using VS 2019 and _MERGE_PROXYSTUB (and some tweaking) in the dialog object did the trick... The standard proxy is maybe wrong here, so it needs to supply its own? 嗯,很好-在对话框对象中使用VS 2019和_MERGE_PROXYSTUB(和一些调整)确实达到了目的……标准代理在这里可能是错误的,因此需要提供自己的代理吗? What the heck, I'm glad it works. 哎呀,我很高兴它能奏效。

@Raymond: thanks for answering - it was the correct track you lead me! @Raymond:感谢您的回答-这是您引导我的正确曲目!

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

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