.Net COM对象需要是STA线程

时间:2015-12-10 22:47:22

标签: c# .net wpf multithreading com

我正在为第三方系统实现.NET COM服务器,即COM客户端(C ++)。我提供了IDL,我曾经用tlbimp生成.dll。在API中,它还建议实现双和接口接口。在这个COM服务器中,我必须实例化一个WPF组件,该组件当前失败,因为它必须从STA线程调用。我已经做了很多关于如何强制我的COM服务器成为线程模型公寓的googeling。我更改了没有帮助的注册表项,然后我在stackoverflow上发现了以下文章:How to make make a .NET COM object apartment-threaded?

我按照说明实现了ICustomQueryInterface,但它失败了;在这里我的IDL:

[
    object,
    uuid(ABB09FED-F7BE-4654-88BC-5F4D2941111A),
    dual,
    nonextensible,
    helpstring("IDVRServer Interface"),
    pointer_default(unique)
]
interface IDVRServer : IDispatch{
    [id(1), helpstring("Creates a DVR Unit Connection based on connection information
    such as IP address, user name...")]
    HRESULT CreateConnection(
    [in] DVRConnectionInfo* pConnInfo, [out, retval] IDVRUnitConnection** ppConn);
};

这里是C#中的实现(包括ICustomQueryInterface):

 [ComVisible(true)]
  [ClassInterface(ClassInterfaceType.AutoDual)
  public class DVRServer : IDVRServer, ICustomQueryInterface
  {
     private IntPtr _dvrPointer;
     public DVRServer() {
        NativeMethods.CoGetStdMarshalEx(this, NativeMethods.SMEXF_SERVER, out _dvrPointer);
      }

 public CustomQueryInterfaceResult GetInterface(ref Guid iid, out IntPtr ppv) {
      if (iid == NativeMethods.IID_IMarshal_DVRServerDispatch)
      {
         res = 0;
         res = Marshal.QueryInterface(_dvrPointer, ref NativeMethods.IID_IMarshal_DVRServerDispatch, out ppv);
         string hex = res.ToString("X");
         if (res != 0)
         {
            return CustomQueryInterfaceResult.Failed;
          }

          return CustomQueryInterfaceResult.Handled;
      }
     return CustomQueryInterfaceResult.Failed;
}
    static class NativeMethods
{

    public static Guid IID_IMarshal_DVRServerDispatch = new Guid("ABB09FED-F7BE-4654-88BC-5F4D2941111A");  
    public const UInt32 SMEXF_SERVER = 1;

    [DllImport("ole32.dll", PreserveSig = true)]
    public static extern void CoGetStdMarshalEx([MarshalAs(UnmanagedType.IUnknown)] object pUnkOuter, UInt32 smexflags, out IntPtr ppUnkInner);
}

Marshal.QueryInterface的结果始终为0x80004002 E_NOINTERFACE。我已经尝试了很多不同的东西,也来自StandardOleMarshalObject和ServicedComponent,但没有任何效果。还有一个问题是,如果注册表完全可以计算,或者我可以忽略那里的ThreadingModel,我从Noseratio的帖子中得不到。提前感谢您对该主题的任何帮助。

我使用VisualStudio 2012和.Net Framework 4。

0 个答案:

没有答案