【问题标题】:Foreach fails with a marshalled COM interfaceForeach 因编组 COM 接口而失败
【发布时间】:2010-10-18 06:25:03
【问题描述】:

我们有一个用 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 上不行。

这种行为的原因是什么?

【问题讨论】:

  • 错误中的 HRESULT 是什么?

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


【解决方案1】:

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

【讨论】:

    【解决方案2】:

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

    您是否检查过IOurCollectionInterface._NewEnum 的实现实际上正在被调用?

    您使用的是哪种 COM 编组?如果是typelib,是否正确注册了typelib?

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


    来自sharptooth的评论:

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

    如果 WinForms 应用程序和服务以不同的用户身份运行,则需要非常仔细地检查安全性。从 COM+ 安全开始,然后使用进程监视器检查注册表/文件访问问题(这似乎不太可能,但总是可能的)。

    【讨论】:

    • 使用了 Typelib 编组并注册了 typelib。更糟糕的是,当从同一台机器上的 WinForms 应用程序调用时,这些东西可以正常工作,但从本地用户下运行的 NT 服务调用时会失败。
    猜你喜欢
    • 2013-03-15
    • 2011-12-20
    • 2014-10-15
    • 2018-09-21
    • 2020-08-21
    • 2014-10-15
    • 1970-01-01
    • 1970-01-01
    • 2012-12-31
    相关资源
    最近更新 更多