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

2024-04-03

我们正在尝试替换最初为 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 应用程序仍然失败并出现相同的错误。


COM 接口的名称不能与IUnknown http://msdn.microsoft.com/en-us/library/ms680509(VS.85).aspx方法名称(QueryInterface、AddRef 和Release http://msdn.microsoft.com/en-us/library/ms682317(VS.85).aspx).

Update

要让您的 C# 类生成 dispinteface(即用于 OLE 自动化绑定的 IDisptach 接口),请使用以下内容装饰您的类类接口属性 http://msdn.microsoft.com/en-us/library/system.runtime.interopservices.classinterfaceattribute.aspx:

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

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

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

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

随机推荐

  • 数据绑定后如何隐藏gridview列?

    我使用以下链接中的解决方案隐藏我的列 如何隐藏 GridView 中的 TemplateField 列 https stackoverflow com questions 4954871 how to hide a templatefiel
  • 消除重复的 try/catch 代码

    编写必须一次又一次处理相同异常的代码总是很无聊 有没有一种方法可以在不使用try catch的情况下编写代码 并向方法添加属性来捕获 并处理 可能发生的各种异常 这听起来像 AOP Postsharp 这会是理想的解决方案吗 因此 我想编写
  • 如何在protobuf消息中添加int数组

    我必须编写一个 protobuf 消息 它应该有 1 个整数变量和一个整数数组 package protobuf message myProto optional uint32 message id 1 optional int updat
  • 无法读取 Angular 4 中 null 的属性“outlets”

    我有 Angular 4 3 6 项目 其中模板片段产生此错误 模板块 a article title a 错误堆栈跟踪 ArticleSpComponent html 26 ERROR TypeError Cannot read prop
  • Android - 在开发和生产 Web 服务之间切换

    我想让我的应用程序在开发和生产 Web 服务之间切换 而不需要对代码进行太多更改 并且相对简单 现在我的网络服务地址为static final String类中的变量执行实际的 HTTP 调用 并使用 a 来切换应用程序其余部分中的代码st
  • 如何执行作为 sp 参数传递的 sql 文本?

    我有一个带有 nvarchar 参数的存储过程 我希望调用者在使用此 SP 时提供 sql 命令的文本 如何从 SP 内执行提供的 sql 命令 这可能吗 我认为可以使用 EXEC 但以下内容 EXEC script 错误表明无法按给定名称
  • 带有 Base64 图像的 v-card-media

    我正在 ColdFusion 中创建验证码图像 并将其作为 Taffy 的 REST feed 返回 然后在 Vuetify 中显示 ColdFusion 太妃糖代码
  • 如何从Excel中获取工作表名称

    如何从 Excel 获取工作表名称并将其添加到我的组合框列表中 我似乎无法将其添加到我的代码中 因为它是public static public static DataTable ExcelToDataTable string fileNa
  • Consumer.endOffsets 在 Kafka 中如何工作?

    假设我有一个无限期运行的计时器任务 它会迭代 kafka 集群中的所有消费者组 并输出每个组的所有分区的延迟 提交偏移量和结束偏移量 与 Kafka 控制台消费者组脚本的工作方式类似 只不过它适用于所有组 就像是 单个消费者 不工作 不返回
  • 如何在Verilog中将二维数组中的所有位设置为0?

    我构建了一个 8 2bits 数组来表示 Verilog 中的一块内存 reg 1 0 m 0 7 该存储器有一个复位信号 如果复位为1 则该存储器中的所有位都应重置为0 但是我不知道如何以简洁的方式设置m的所有位 因为如果有数百个内存中有
  • 如何防止 WCF 服务进入故障状态?

    我有一个 WCF 服务不应进入故障状态 如果出现异常 则应将其记录下来 并且服务应继续不间断 该服务具有单向操作契约 并且正在从 MSMQ 读取消息 我的问题有两个 该服务似乎正在被吞噬 异常 错误 所以我无法 调试它 我如何获得服务 暴露
  • 从 Google 云端硬盘文件夹中删除旧文件

    我创建了这个脚本来删除 3 个多小时前发布的文件 而且即使最新文件超过 3 小时 也不会被删除 因此该文件夹永远不会为空 我启用了谷歌的高级服务 称为 DRIVE API V2 我激活了一个触发器 每 5 分钟分析一次文件夹 但文件通常不会
  • “此哈希方法尚未发现冲突”是什么意思?

    我的意思是我不需要寻找实际的碰撞 就知道它们的存在 如果没有冲突 那么如何获得固定长度的结果呢 这就是为什么我不明白人们声称 md5 不安全 是什么意思 有人发现了碰撞 或者类似的东西 我唯一能想到的是 碰撞搜索仅查找字典单词 例如 如果
  • 如何知道已保存模型中的输出和输入张量名称

    我知道如何加载已保存的 TensorFlow 模型 但如何知道输入和输出张量名称 我可以使用 tf import graph def 加载 protobuf 文件 然后使用函数 get tensor by name 加载张量 但我如何知道任
  • 如何在 CLion 中运行 SFML,错误未定义引用?

    我是 C 新手 尝试学习游戏编程 我选择 SFML 并在 Jetbrain 的 CLion 上运行并使用 Ubuntu 机器 我按照这个教程SFML 和 Linux http sfml dev org tutorials 2 0 start
  • Primefaces 嵌套对话框/'appendToBody' - 支持 bean 操作未触发

    我在两个嵌套表单中有一个支持 bean 方法 会话范围 该方法不会触发 我用一个展示问题的通用示例提出了这个问题 我希望了解如何 为何使用表单 对话框和appendToBody标签导致了问题 为了澄清 该行动contentsOfDialog
  • 如何阻止 Eclipse 每次重新启动时累积 Tomcat 实例?

    我在 Eclipse 2019 3 中运行 Tomcat 8 5 每次我通过单击绿色圆圈 三角形按钮重新启动 Tomcat 实例时 最终都会运行重复的实例 我怎样才能阻止这种情况发生 这是我已经尝试过的一些事情 我尝试升级到tomcat 9
  • PostgreSQL 9.3:将一列拆分为多列

    我想拆分一列colb在下面给出的示例中分为两列 喜欢column1 and column2 我有一个包含两列的表 Example create table t3 cola varchar colb varchar 插入 insert int
  • 在 Angular 中动态设置样式

    我有以下标记 tr style background color none tr 正如它所说 如果activity status字段待定 然后将背景颜色设置为红色 否则设置为绿色 但这不起作用 检查后我发现它呈现如下 tr style ba
  • C# - 编写 COM 服务器 - 映射到方法的属性

    我们正在尝试替换最初为 VB6 应用程序编写的 COM 服务器 我们无法访问源代码 由于某种原因 VB6 应用程序可以调用我们的构造函数 但随后它会得到 系统错误 H80004002 没有这样的 接口支持 我假设当它尝试使用 QueryIn