Foreach使用编组的COM接口失败

时间:2009-04-08 09:04:48

标签: c# .net com interop windows-server-2008

我们在C ++中使用ATL编写了一个32位COM组件。当需要从64位.NET使用它时,我们创建一个COM +应用程序,一切正常。

最近我们注意到Win2k8上的奇怪行为。组件中的COM对象触发事件,我们在.NET代码中处理它。该事件还有一个参数也从非托管代码传递。

以下是澄清的部分定义(IDL表示法):

interface IOurCollectionInterface : IDispatch 
{
[propget, restricted, id(DISPID_NEWENUM)]]
HRESULT _NewEnum( [out, retval] IUnknown** result );
}

interface IOurObjectInterface : IDispatch 
{
[propget]
HRESULT Collection( [out, retval] IOurCollectionInterface** result );
}

事件处理程序传递一个IOurObjectInterface实例。在里面我们尝试运行foreach()循环。

void onEvent( IOurObjectInterface ourObject )
{
    foreach( object element in ourObject.Collection ) {
       //do stuff
    }
}

代码在 foreach 的行上崩溃,并带有以下消息: IEnumVARIANT的QI在非托管服务器上失败

IEnumVARIANT肯定是由IOurCollectionInterface::get__NewEnum()实现返回的对象实现的。上面的代码可以在WinXP和Win2k3上运行,但在Win2k8上没有。

这种行为的原因是什么?

2 个答案:

答案 0 :(得分:0)

很难确定。但是会怀疑是一个编组问题。

您是否检查过实际调用了IOurCollectionInterface._NewEnum的实现?

您使用什么类型的COM编组?如果是typelib,是正确注册的typelib吗?

如果在进程中实现接口,它是否有效?


来自sharptooth的评论:

  

使用Typelib编组并注册typelib。更糟糕的是,当从同一台机器上的WinForms应用程序调用时,这个东西可以正常工作,但是当从本地用户下运行的NT服务调用时会失败。

如果WinForms应用和服务作为不同的用户运行,请非常仔细地检查安全性。从COM +安全性开始,然后使用Process Monitor检查注册表/文件访问问题(这似乎不太可能,但总是可行的)。

答案 1 :(得分:0)

尝试使用系统帐户运行并检查事件以获取有关错误的更多信息。