IConnectionPoint :: Advise больше не работает в Windows 10 "1903" из неосновного потока - PullRequest
0 голосов
/ 13 мая 2019

У нас есть приложение, которое запускает некоторый хостинг COM в основном потоке или в другом потоке (асинхронном), и мы хотели бы подключиться к этому (подключаемому) объекту с помощью стандартных интерфейсов ConnectionPoint для получения его событий..

До Windows 10 SP 1903 это работало.

Но при тестировании приложения в «обновлении 1903» IConnectionPoint->Advise() завершается ошибкой с CONNECT_E_CANNOTCONNECT, когда код запускается в другомчем начальный поток - пока вызывается Advise (), сервер событий запрашивает много интерфейсов, которые я не поддерживаю, я поддерживаю только IUnknown, IDispatch и интерфейс событий, как и должно быть.

Есть многоинтерфейсов, запрашиваемых, когда все это выполняется в главном потоке, отличном от STA, за исключением <1903, а в 1903 году это: </p>

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 () и т. д.) в потоке сценариятак что диалоговый элемент управления может запускать события, используя объект в хосте сценариев

Так что, если есть необходимость сделать маршаллинг, теперь я предполагаю, что он находится внутри диалогового элемента управления, который должен маршалировать указатель, который я передаюПосоветуйте (), по крайней мере, это то, что я прочитал в глубине WWW.Поскольку мы здесь ничего не делаем, он использует стандартный маршаллер, маршаллинг выполняется (или, по крайней мере, пытался сделать) с помощью комбинации! 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 года.Итак, мой вопрос: почему это может быть неудачным, и что должен предоставить мой класс, когда я все советую ()?

Или сервер (подключаемый объект) создается в главном потоке STA и должен каким-то образом изменяться для поддержки маршалинга в приемник событий нового потока, вызывающего Advise ()?

Почтитот же стек был найден в предыдущих версиях, но это удалось.

1 Ответ

0 голосов
/ 14 мая 2019

Ах, хорошо - использование VS 2019 и _MERGE_PROXYSTUB (и некоторая настройка) в объекте диалога сделали свое дело ... Стандартный прокси-сервер здесь может быть неправильным, поэтому он должен предоставить свой собственный? Какого черта, я рад, что это работает.

@ Raymond: спасибо, что ответили - это был правильный трек, который ты вел меня!

...