简体   繁体   English

从 COM 库转换到接口在 IIS 中的第 16 个托管线程上失败(InvalidCastException,WinRT 产生错误 0x80040155)

[英]Casting to an interface from a COM library fails on the 16th managed thread within IIS (InvalidCastException, WinRT originate error 0x80040155)

I'm posting this mostly for anyone else that hits this weird issue, and if anyone can shed a light on why IIS/Cassini is being a devil.我主要是为遇到这个奇怪问题的其他人发布这篇文章,如果有人能解释为什么 IIS/Cassini 是一个魔鬼。

For the most part, we can successfully cast a Dispatch object defined in ODL as在大多数情况下,我们可以成功地将 ODL 中定义的 Dispatch 对象转换为

[ uuid(GUID_FOO) ]
dispinterface IFooDisp
{
    ... properties & methods.
};
[ uuid(GUID_FOO_COCLASS),noncreatable ]
coclass FooDisp
{
    [default] dispinterface IFooDisp;
};

to the following interface到以下界面

[ uuid(GUID_BAR) ]
interface IBar : IUnknown
{
    ... some methods
}

The above are both implemented in a registered C++ OLE/COM automation DLL, and a typelibrary is used to create an Interop DLL and it's regasm'd.以上都是在注册的 C++ OLE/COM 自动化 DLL 中实现的,并且类型库用于创建互操作 DLL 并重新加注。

So In C# we successfully and repeatedly can call所以在 C# 中我们可以成功地重复调用

myFoo as IBar

and

(IBar) myFoo

Without any trouble.没有任何麻烦。 Until....直到....

We discovered that if we open a web page, go to a URL on the server, close the browser and repeat 16 times (Cassini or IIS), that when the 16th managed thread is created, suddenly the cast fails with an underlying exception of:我们发现,如果我们打开一个网页,转到服务器上的一个 URL,关闭浏览器并重复 16 次(Cassini 或 IIS),当创建第 16 个托管线程时,突然转换失败,底层异常为:

    Exception Thrown at 0x75151812 (KernelBase.dll) in My.exe: 
WinRT originate error - 0x80040155 : 'Failed to find proxy registration for IID: {GUID_BAR}.' 

When testing测试时

(myFoo as IBar)!=null

The cast returns null all of a sudden.演员表突然返回 null。 But the object itself is still valid and can be interrogated, just not casted any more.但是对象本身仍然有效并且可以被询问,只是不再被强制转换。

Why does it fail on the 16th thread, and work fine beforehand?为什么它在第 16 个线程上失败,并且事先工作正常? Ps everything is set to STA. Ps一切都设置为STA。 How do I fix this?我该如何解决?

I can tell you how to fix it, add oleautomation to the IBar attributes.我可以告诉你如何修复它,将oleautomation添加到 IBar 属性。 But I'm not sure why it's necessary.但我不确定为什么有必要。

How did I get there?我是怎么到那里的?

Given that error code, I checked the registry, as I know from painful experience, that C# or OLE loves to have interfaces defined in the registry so it knows what to do, rather than using the details of Interops/TLB.鉴于该错误代码,我检查了注册表,正如我从痛苦的经验中了解到的那样,C# 或 OLE 喜欢在注册表中定义接口,因此它知道要做什么,而不是使用 Interops/TLB 的详细信息。

On searching, I discovered that the registry didn't contain GUID_BAR as a key, and thus no proxy/stub details, like all the other interfaces.在搜索时,我发现注册表不包含 GUID_BAR 作为键,因此没有代理/存根详细信息,就像所有其他接口一样。

Grabbing at straws I thought, what if it just needed the registry key to exist?抓住稻草我想,如果它只需要注册表项存在怎么办? So I added attributes one by one until the right one pushed the registry settings in, adding oleautomation to the IBar interface attribute did the trick.所以我一一添加属性,直到正确的属性将注册表设置推入,将oleautomation添加到 IBar 接口属性就成功了。 It suddenly fixed it, no more failures to cast.它突然修复了它,没有更多的失败铸造。

But I don't know why C# was working fine up to the 16th managed thread.但我不知道为什么 C# 在第 16 个托管线程之前都能正常工作。 Each thread has it's own set of objects (no cross thread calls, and a 1:1 mapping of managed to COM threads).每个线程都有它自己的一组对象(没有跨线程调用,以及托管到 COM 线程的 1:1 映射)。 In attempting to reproduce this with an automated test, simply creating hundreds of threads and doing similar work does not cause the same failure.在尝试通过自动化测试重现这一点时,简单地创建数百个线程并执行类似的工作不会导致相同的失败。 It must be something special about IIS.它一定是 IIS 的特别之处。

Maybe the meta data gets cleared and re-gathered?也许元数据被清除并重新收集? Can someone explain more?有人可以解释更多吗?

暂无
暂无

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

相关问题 Unable to cast COM object of type 'Microsoft.Office.Interop.Outlook.ApplicationClass' {00063001-0000-0000-C000-000000000046} HRESULT: 0x80040155 - Unable to cast COM object of type 'Microsoft.Office.Interop.Outlook.ApplicationClass' {00063001-0000-0000-C000-000000000046} HRESULT: 0x80040155 如何覆盖从托管对象到COM接口的转换? - How to override casting from a managed object to a COM interface? 将实体强制转换为接口以在静态方法中使用时的InvalidCastException - InvalidCastException when casting an entity to a interface for use within a static method InvalidCastException:无法将类型x的COM对象转换为接口类型y - InvalidCastException: Unable to cast COM object of type x to interface type y 动态转换为接口时出现InvalidCastException - InvalidCastException when casting dynamically to interface QueryInterface在强制转换到COM接口实现内部时失败 - QueryInterface fails at casting inside COM-interface implementation 尝试将 COM 类转换为接口时出现“InvalidCastException” - 'InvalidCastException' while trying to cast COM class to interface ClosedXml四舍五入到小数点后16位,我在寻找更高的算术精度(小数点后20位) - ClosedXml is rounding off to 16th decimal where I am looking for higher Arithmetic precision(20th decimal place) 使用COM接口时System.InvalidCastException - System.InvalidCastException when using a COM interface 从子级转换为父级时发生InvalidCastException - InvalidCastException when casting from child to parent
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM