为什么我不能投我的COM对象来实现它在C#中的接口? [英] Why cannot I cast my COM object to the interface it implements in C#?

查看:298
本文介绍了为什么我不能投我的COM对象来实现它在C#中的接口?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在DLL(此代码显示在从元数据的Visual Studio)这个接口:

I have this interface in the dll (this code is shown in Visual Studio from metadata):

#region Assembly XCapture.dll, v2.0.50727
// d:\svn\dashboard\trunk\Source\MockDiagnosticsServer\lib\XCapture.dll
#endregion

using System;
using System.Runtime.InteropServices;

namespace XCapture
{
    [TypeLibType(4160)]
    [Guid("XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX")]
    public interface IDiagnostics
    {
        [DispId(1)]
        void GetStatusInfo(int index, ref object data);
    }
}



所以,我创建了这样的类的COM服务器:

So I created a COM server with such class:

[ComVisible(true)]
[Guid(SimpleDiagnosticsMock.CLSID)]
[ComDefaultInterface(typeof(IDiagnostics))]
[ClassInterface(ClassInterfaceType.None)]
public class SimpleDiagnosticsMock : ReferenceCountedObject, IDiagnostics
{
    public const string CLSID = "281C897B-A81F-4C61-8472-79B61B99A6BC";

    // These routines perform the additional COM registration needed by 
    // the service. ---- stripped from example

    void IDiagnostics.GetStatusInfo(int index, ref object data)
    {
        Log.Info("GetStatusInfo called with index={0}, data={1}", index, data);

        data = index.ToString();
    }
}



服务器似乎做工精细,我能使用从一个VBScript的对象。但后来我尝试从另一个C#客户端使用它:

Server seems to work fine, and I am able to use the object from a VBScript. But then I try to use it from another C# client:

    [STAThread]
    static void Main(string[] args)
    {
        Guid mockClsId = new Guid("281C897B-A81F-4C61-8472-79B61B99A6BC");
        Type mockType = Type.GetTypeFromCLSID(mockClsId, true);
        IDiagnostics mock = (IDiagnostics)Activator.CreateInstance(mockType);

        //var diag = mock as IDiagnostics;

        object s = null;
        mock.GetStatusInfo(3, ref s);

        Console.WriteLine(s);
        Console.ReadKey();
    }

和它失败

无法转换类型'系统.__ ComObject的COM对象的接口
型'XCapture.IDiagnostics。此操作失败的原因是对IID
'{XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX}接口的COM组件上的
QueryInterface调用失败,原因是下面的
错误:没有这样的接口支持(从HRESULT异常:0x80004002
(E_NOINTERFACE))。

Unable to cast COM object of type 'System.__ComObject' to interface type 'XCapture.IDiagnostics'. This operation failed because the QueryInterface call on the COM component for the interface with IID '{XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX}' failed due to the following error: No such interface supported (Exception from HRESULT: 0x80004002 (E_NOINTERFACE)).

我在做什么错

我也尝试使用InvokeMember,而不同之处在于我是不是能够得到裁判退回的数据还挺工作参数。

I have also tried to use InvokeMember, and that kinda worked except that I wasn't able to get the ref-returned data parameter.

编辑:添加STAThread属性来我的主要过程。这并没有解决问题,但您的真的应该的,除非你是绝对肯定你不需要它使用STAThread与COM。请参见下面汉斯帕桑特的答案。

added STAThread attribute to my Main procedure. This does not solve the issue, but you really should use STAThread with COM unless you're absolutely sure you don't need it. See Hans Passant's answer below.

推荐答案

所以,是我与IDiagnostics接口DLL是从TLB中产生的问题,那TLB从来没有得到注册。

So, the problem was that my DLL with IDiagnostics interface was generated from a TLB, and that TLB never got registered.

由于DLL是从TLB进口,RegAsm.exe拒绝登记库中。所以我用在 regtlibv12.exe 工具注册的TLB本身:

Since the DLL was imported from the TLB, RegAsm.exe refuses to register the library. So I used the regtlibv12.exe tool to register the TLB itself:

C:\Windows\Microsoft.NET\Framework\v4.0.30319\regtlibv12.exe "$(ProjectDir)\lib\Diagnostics.tlb"

然后,一切都奇迹般地开始工作。

Then everything magically started to work.

由于regtlibv12是不受支持的工具,我还是不知道该怎么办这个正常。

Since regtlibv12 is not a supported tool, I still don't know how to do this properly.

这篇关于为什么我不能投我的COM对象来实现它在C#中的接口?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆