在C#中为windows API编写COM服务器,从何开始

本文关键字:何开始 开始 服务器 中为 windows API COM 编写 | 更新日期: 2023-09-27 18:25:53

我正在尝试编写一些插件来使用终端服务会话代理插件接口。我的C#非常流利,但自从90年代末以来,我就没有做过任何C++。对于我正在编写的插件,我计划与数据库通信,我更喜欢使用System.Data.SqlClient与它交谈,因为我知道它的来龙去脉相当好。我有Windows SDK,它为我的接口(tssbx.idl)提供了.idl文件。SDK还提供了一个C头文件(tssbx.h)和一个C源文件(tssbx_i.c)。

我以前从未编写过COM服务器,在学习如何读取IDL文件并将其转换为C#时,我一直很难找到资源。我发现的所有内容都写着"使用TlbImport",但这需要像块library这样的东西在IDL中,而tssbx.idl(及其从属项)没有实现。

什么是我的最佳选择:

  1. 为C#找到一个等效于MIDL的工具,用于将.idl文件解析为.cs文件
  2. 学习IDL(我一直很难找到好的学习指南),并用C#手工编写整个内容
  3. 使用提供的C文件编写一个助手dll,并将该调用用于我的.NET部分的C#dll
  4. 重新学习C++,使用提供的.h和.C文件,并使用CLR进行.NET调用
  5. 其他一些我没有想到的选择

在C#中为windows API编写COM服务器,从何开始

您尝试做的事情的方法是将IDL定义转换为C#接口,然后将这些接口实现为C#类。将适当的属性(主要是ComVisible、ClassInterface和ProgId)应用于要向COM公开的类,并使用regasm工具将程序集注册为COM服务器。

将IDL转换成C#实际上并没有那么复杂;在大多数情况下,它非常直接地从IDL关键字映射到C#关键字和/或MarshalAs属性。我有一系列关于如何使用tlbimp进行COM互操作的博客文章,其中包括一篇关于如何读取IDL的文章。我不知道有什么工具能很好地做到这一点,但如果它是Windows SDK的一部分,你应该先检查pinvoke.net,以防其他人帮你做。

就你的其他选择而言,3和4都差不多。除非通过COM互操作或混合模式C++库完成,否则不能直接从非托管代码调用托管代码。在第一种情况下,你仍然需要解决所有的问题,让你的C#程序集在COM中注册,以便调用你的dll,所以你可以跳过中间人。第二,你基本上是在手动做与运行时的互操作代码相同的事情,并使用一种你不太熟悉的语言来引导,这对我来说似乎是一个净损失。

不过,请注意,将.NET程序集加载到非托管上下文中并不总是可能的;例如,Windows 2008中明确不支持托管shell扩展。我不知道TSSBX接口是否允许您将托管程序集加载为COM对象,所以您必须意识到这种可能性。如果你做不到,那么你的任何选项都不会起作用,你必须避免使用.NET Framework,使用其他一些数据库访问技术,并用非托管C++编写整个项目。

我将此作为答案发布,因为它太长了,无法发表评论

据我所知,在.NET中编写此类插件可能会在以后引发问题,尤其是在必须加载多个基于.NET的插件,而两个(或多个)插件使用不同.NET版本的情况下(此类问题已在shell扩展的上下文中明确提出-我只是将该场景中的原因作为我怀疑的基础…)。

至于您的选项IDL-ield不能实现任何东西-它是一种接口描述语言

我建议使用类似选项#3的东西,并进行一些修改:

将.NET部分实现为Windows服务,并通过IPC在C和.NET之间进行通信-我建议使用共享内存,该内存速度极快,并且受到.NET4.的良好支持