我在客户环境中有一个非常奇怪的问题——我有一个调用 3 或 4 个进程内 COM 对象 (dll) 的 exe。这些 dll 还相互调用和调用主 exe(通过 COM 事件)。
这工作了很长时间(5 年?)并且继续在数千台机器上正常工作,但是对于一个客户(Windows 2008 R2),整个系统变得混乱:主 exe 创建了一个普通的普通公寓线程 COM 对象(没有自定义编组)使用 CoCreateInstance 并开始调用其方法。
几十或一百次调用一切正常,但随后发生了真正出乎意料的事情:对进程内 COM 对象之一的调用(它实际上是 COM 返回的代理)被编组到由 COM 创建的单独线程。该方法回调到主 exe,但该调用再次被编组到另一个线程。并且该线程上的代码开始访问控件,这就是真正糟糕的事情开始发生的时候——主线程被阻塞,并且从辅助线程阻塞(SentMessage、GetPropW 等)访问在主线程上创建的控件。
有人见过这个吗?
有什么方法可以禁用此行为或完全摆脱 COM 编组(在这种情况下这是无用的,因为我的应用程序没有创建线程)?
我用我自己的函数替换了 CoCreateInstance(),给定类 GUID,计算可执行路径,加载它,调用 DllgetClassObject,然后调用 IClassFactory::CreateObject。这工作得很好,我所有的对象现在都在主线程上运行。但是进程外对象(我的 CoCreateInstance 版本没有涉及)也开始失败,并出现非常相似的错误:我创建了 Outlook.Application 对象的实例,然后创建了一个新的 MailItem 对象。现在访问该对象上的任何属性都会返回 'The application called an interface that was marshalled for a different thread'。不是!我在创建对象时记录了线程 ID。所有的调用都在主线程上!
帮助!我该如何阻止这种疯狂?
谢谢!