C# - 编写COM服务器 - 映射到方法的属性

时间:2009-10-23 16:57:55

标签: c# .net com vb6 idl

我们正在尝试替换最初为VB6应用程序编写的COM服务器

我们无权访问源代码。

出于某种原因,VB6应用程序可以调用我们的构造函数,但随后它会得到:

  

系统错误& H80004002。没有这样的   界面支持。

我假设它尝试使用QueryInterface获取接口。

我们通过regasm / tlb和gacutil正确发送了我们的程序集,但后来我发现了一些奇怪的东西。我打开了为程序集生成的.tlb文件regasm,并注意到我界面上的所有属性都显示为方法。

.Net工具正在做什么?这会导致我的问题吗?

以下是原始文件的完整tlb定义:

// Generated .IDL file (by the OLE/COM Object Viewer)
// 
// typelib filename: UtopiaKeyboard.tlb

[
  uuid(9B4E1840-FF65-11CF-AA2E-0020AFA49D5A),
  version(1.0),
  helpstring("OPOS POSKeyboard OLE Control")
]
library POSKEYBOARDLib
{
    // TLib :     // TLib : OLE Automation : {00020430-0000-0000-C000-000000000046}
    importlib("STDOLE2.TLB");

    // Forward declare all types defined in this typelib
    dispinterface _DPOSKeyboard;
    dispinterface _DPOSKeyboardEvents;

    [
      uuid(9B4E1841-FF65-11CF-AA2E-0020AFA49D5A),
      helpstring("Dispatch interface for OPOS POSKeyboard OLE Control"),
      hidden
    ]
    dispinterface _DPOSKeyboard {
        properties:
            [id(0x00000001)            
]
            BSTR CheckHealthText;
            [id(0x00000002)            
]
            VARIANT_BOOL Claimed;
            [id(0x00000003)            
]
            VARIANT_BOOL DataEventEnabled;
            [id(0x00000004)            
]
            VARIANT_BOOL DeviceEnabled;
            [id(0x00000005)            
]
            VARIANT_BOOL FreezeEvents;
            [id(0x00000006)            
]
            long ResultCode;
            [id(0x00000007)            
]
            long ResultCodeExtended;
            [id(0x00000008)            
]
            long State;
            [id(0x00000009)            
]
            BSTR ControlObjectDescription;
            [id(0x0000000a)            
]
            long ControlObjectVersion;
            [id(0x0000000b)            
]
            BSTR ServiceObjectDescription;
            [id(0x0000000c)            
]
            long ServiceObjectVersion;
            [id(0x0000000d)            
]
            BSTR DeviceDescription;
            [id(0x0000000e)            
]
            BSTR DeviceName;
            [id(0x0000000f)            
]
            long POSKeyData;
            [id(0x0000001a)            
]
            VARIANT_BOOL AutoDisable;
            [id(0x0000001b)            
]
            long BinaryConversion;
            [id(0x0000001c)            
]
            long DataCount;
            [id(0x0000001d)            
]
            VARIANT_BOOL CapKeyUp;
            [id(0x0000001e)            
]
            long EventTypes;
            [id(0x0000001f)            
]
            long POSKeyEventType;
            [id(0x00000021)            
]
            long CapPowerReporting;
            [id(0x00000022)            
]
            long PowerNotify;
            [id(0x00000023)            
]
            long PowerState;
        methods:
            [id(0x00000010)]
            long Open([in] BSTR DeviceName);
            [id(0x00000011)]
            long Close();
            [id(0x00000012)]
            long Claim([in] long Timeout);
            [id(0x00000013)]
            long Release();
            [id(0x00000014)]
            long CheckHealth([in] long Level);
            [id(0x00000015)]
            long ClearInput();
            [id(0x00000016)]
            long DirectIO(
                            [in] long Command, 
                            [in, out] long* pData, 
                            [in, out] BSTR* pString);
            [id(0x00000017)]
            void SOData([in] long Status);
            [id(0x00000018)]
            void SODirectIO(
                            [in] long EventNumber, 
                            [in, out] long* pData, 
                            [in, out] BSTR* pString);
            [id(0x00000019)]
            void SOError(
                            [in] long ResultCode, 
                            [in] long ResultCodeExtended, 
                            [in] long ErrorLocus, 
                            [in, out] long* pErrorResponse);
            [id(0x00000020)]
            long SOProcessID();
            [id(0x00000024)]
            void SOStatusUpdate([in] long Status);
    };

    [
      uuid(9B4E1842-FF65-11CF-AA2E-0020AFA49D5A),
      helpstring("Event interface for OPOS POSKeyboard OLE Control")
    ]
    dispinterface _DPOSKeyboardEvents {
        properties:
        methods:
            [id(0x00000001)]
            void DataEvent([in] long Status);
            [id(0x00000002)]
            void DirectIOEvent(
                            [in] long EventNumber, 
                            [in, out] long* pData, 
                            [in, out] BSTR* pString);
            [id(0x00000003)]
            void ErrorEvent(
                            [in] long ResultCode, 
                            [in] long ResultCodeExtended, 
                            [in] long ErrorLocus, 
                            [in, out] long* pErrorResponse);
            [id(0x00000004)]
            void StatusUpdateEvent([in] long Status);
    };

    [
      uuid(9B4E1843-FF65-11CF-AA2E-0020AFA49D5A),
      helpstring("OPOS POSKeyboard OLE Control"),
      control
    ]
    coclass POSKeyboard {
        [default] dispinterface _DPOSKeyboard;
        [default, source] dispinterface _DPOSKeyboardEvents;
    };
};

这是我的.Net程序集的生成tlb:

// Generated .IDL file (by the OLE/COM Object Viewer)
// 
// typelib filename: POSKEYBOARDLib.tlb

[
  uuid(9B4E1840-FF65-11CF-AA2E-0020AFA49D5A),
  version(1.0),
  custom(90883F05-3D28-11D2-8F17-00A0C9A6186D, "POSKEYBOARDLib, Version=1.0.0.0, Culture=neutral, PublicKeyToken=5824208931aaf68b")

]
library POSKEYBOARDLib
{
    // TLib :     // TLib : mscorlib.dll : {BED7F4EA-1A96-11D2-8F08-00A0C9A6186D}
    importlib("mscorlib.tlb");
    // TLib : OLE Automation : {00020430-0000-0000-C000-000000000046}
    importlib("STDOLE2.TLB");

    // Forward declare all types defined in this typelib
    dispinterface _DPOSKeyboard;
    dispinterface _DPOSKeyboardEvents;

    [
      uuid(9B4E1841-FF65-11CF-AA2E-0020AFA49D5A),
      version(1.0),
      custom(0F21F359-AB84-41E8-9A78-36D110E6D2F9, "POSKEYBOARDLib._DPOSKeyboard")    

    ]
    dispinterface _DPOSKeyboard {
        properties:
        methods:
            [id(0x00000001), propget]
            BSTR CheckHealthText();
            [id(0x00000001), propput]
            void CheckHealthText([in] BSTR rhs);
            [id(0x00000002), propget]
            VARIANT_BOOL Claimed();
            [id(0x00000002), propput]
            void Claimed([in] VARIANT_BOOL rhs);
            [id(0x00000003), propget]
            VARIANT_BOOL DataEventEnabled();
            [id(0x00000003), propput]
            void DataEventEnabled([in] VARIANT_BOOL rhs);
            [id(0x00000004), propget]
            VARIANT_BOOL DeviceEnabled();
            [id(0x00000004), propput]
            void DeviceEnabled([in] VARIANT_BOOL rhs);
            [id(0x00000005), propget]
            VARIANT_BOOL FreezeEvents();
            [id(0x00000005), propput]
            void FreezeEvents([in] VARIANT_BOOL rhs);
            [id(0x00000006), propget]
            long ResultCode();
            [id(0x00000006), propput]
            void ResultCode([in] long rhs);
            [id(0x00000007), propget]
            long ResultCodeExtended();
            [id(0x00000007), propput]
            void ResultCodeExtended([in] long rhs);
            [id(0x00000008), propget]
            long State();
            [id(0x00000008), propput]
            void State([in] long rhs);
            [id(0x00000009), propget]
            BSTR ControlObjectDescription();
            [id(0x00000009), propput]
            void ControlObjectDescription([in] BSTR rhs);
            [id(0x0000000a), propget]
            long ControlObjectVersion();
            [id(0x0000000a), propput]
            void ControlObjectVersion([in] long rhs);
            [id(0x0000000b), propget]
            BSTR ServiceObjectDescription();
            [id(0x0000000b), propput]
            void ServiceObjectDescription([in] BSTR rhs);
            [id(0x0000000c), propget]
            long ServiceObjectVersion();
            [id(0x0000000c), propput]
            void ServiceObjectVersion([in] long rhs);
            [id(0x0000000d), propget]
            BSTR DeviceDescription();
            [id(0x0000000d), propput]
            void DeviceDescription([in] BSTR rhs);
            [id(0x0000000e), propget]
            BSTR DeviceName();
            [id(0x0000000e), propput]
            void DeviceName([in] BSTR rhs);
            [id(0x0000000f), propget]
            long POSKeyData();
            [id(0x0000000f), propput]
            void POSKeyData([in] long rhs);
            [id(0x00000010)]
            long Open([in] BSTR DeviceName);
            [id(0x00000011)]
            long Close();
            [id(0x00000012)]
            long Claim([in] long Timeout);
            [id(0x00000013)]
            long Release();
            [id(0x00000014)]
            long CheckHealth([in] long Level);
            [id(0x00000015)]
            long ClearInput();
            [id(0x00000016)]
            long DirectIO(
                            [in] long Command, 
                            [in, out] long* pData, 
                            [in, out] BSTR* pString);
            [id(0x00000017)]
            void SOData([in] long Status);
            [id(0x00000018)]
            void SODirectIO(
                            [in] long EventNumber, 
                            [in, out] long* pData, 
                            [in, out] BSTR* pString);
            [id(0x00000019)]
            void SOError(
                            [in] long ResultCode, 
                            [in] long ResultCodeExtended, 
                            [in] long ErrorLocus, 
                            [in, out] long* pErrorResponse);
            [id(0x0000001a), propget]
            VARIANT_BOOL AutoDisable();
            [id(0x0000001a), propput]
            void AutoDisable([in] VARIANT_BOOL rhs);
            [id(0x0000001b), propget]
            long BinaryConversion();
            [id(0x0000001b), propput]
            void BinaryConversion([in] long rhs);
            [id(0x0000001c), propget]
            long DataCount();
            [id(0x0000001c), propput]
            void DataCount([in] long rhs);
            [id(0x0000001d), propget]
            VARIANT_BOOL CapKeyUp();
            [id(0x0000001d), propput]
            void CapKeyUp([in] VARIANT_BOOL rhs);
            [id(0x0000001e), propget]
            long EventTypes();
            [id(0x0000001e), propput]
            void EventTypes([in] long rhs);
            [id(0x0000001f), propget]
            long POSKeyEventType();
            [id(0x0000001f), propput]
            void POSKeyEventType([in] long rhs);
            [id(0x00000020)]
            long SOProcessID();
            [id(0x00000021), propget]
            long CapPowerReporting();
            [id(0x00000021), propput]
            void CapPowerReporting([in] long rhs);
            [id(0x00000022), propget]
            long PowerNotify();
            [id(0x00000022), propput]
            void PowerNotify([in] long rhs);
            [id(0x00000023), propget]
            long PowerState();
            [id(0x00000023), propput]
            void PowerState([in] long rhs);
            [id(0x00000024)]
            void SOStatusUpdate([in] long Status);
    };

    [
      uuid(9B4E1842-FF65-11CF-AA2E-0020AFA49D5A),
      version(1.0),
      custom(0F21F359-AB84-41E8-9A78-36D110E6D2F9, "POSKEYBOARDLib._DPOSKeyboardEvents")    

    ]
    dispinterface _DPOSKeyboardEvents {
        properties:
        methods:
            [id(0x00000001)]
            void DataEvent([in] long Status);
            [id(0x00000002)]
            void DirectIOEvent(
                            [in] long EventNumber, 
                            [in, out] long* pData, 
                            [in, out] BSTR* pString);
            [id(0x00000003)]
            void ErrorEvent(
                            [in] long ResultCode, 
                            [in] long ResultCodeExtended, 
                            [in] long ErrorLocus, 
                            [in, out] long* pErrorResponse);
            [id(0x00000004)]
            void StatusUpdateEvent([in] long Status);
    };

    [
      uuid(9B4E1843-FF65-11CF-AA2E-0020AFA49D5A),
      version(1.0),
      custom(0F21F359-AB84-41E8-9A78-36D110E6D2F9, "POSKEYBOARDLib.POSKeyboard")
    ]
    coclass POSKeyboard {
        interface _Object;
        [default] dispinterface _DPOSKeyboard;
        [default, source] dispinterface _DPOSKeyboardEvents;
    };
};

不知何故,我的属性被列为方法......即使我添加了PreserveSig,它仍会写入2个方法,而不是使它们成为属性。

我应该尝试将哪些更改与原始tlb相同?或者至少让它发挥作用。

更新:找到我在事件界面上没有DispIdAttribute的地方。修复了这个问题,但是VB6应用程序仍然出现了同样的错误。

3 个答案:

答案 0 :(得分:2)

您不能拥有名称与IUnknown方法名称重叠的COM接口(QueryInterface,AddRef和Release)。

<强>更新

要让您的C#类生成一个dispinteface(即用于OLE自动化绑定的IDisptach接口),请使用ClassInterfaceAttribute装饰您的类:

[ClassInterface(ClassInterfaceType.AutoDispatch)]
class myClass
{
   public string Foo {get;}
   public long Bar();
}

这将生成自动化属性Foo和方法Bar,而不是原始COM接口。

答案 1 :(得分:1)

您曾试图使用链接中包含的信息:
Visual Basic: Inspect COM Components Using the TypeLib Information Object Library

[编辑]
看看tlbimp.exe工具是否可以为您提供帮助。

答案 2 :(得分:0)

好吧,我想通了......

我在目标应用上使用vb6反编译器反编译并导出为vb6项目。

使用VS 2008打开它,升级到VB .Net。

运行应用程序并看到错误“无法转换为IOleObject”。

谷歌搜索,发现System.Windows.Forms.Control实现了这个界面,所以继承Control解决了我的问题。