在C#中为Windows API编写COM服务器,从哪里开始?

时间:2012-02-27 16:30:59

标签: c# c++ .net winapi com

我正在尝试编写一些插件来处理Terminal Services Session Broker Plugin Interface。我对C#非常流利,但自90年代末以来我没有做过任何C ++。对于我正在编写的插件,我计划与数据库进行通信,我更愿意使用System.Data.SqlClient与之交谈,因为我知道它的来龙去脉。我有Windows SDK为我提供了接口(tssbx.idl)的.idl文件。 SDK还提供C头文件(tssbx.h)和C源文件(tssbx_i.c)。

我之前从未编写过COM服务器,而且在学习如何读取IDL文件并将其转换为C#时遇到了很多困难。我找到的所有内容都说“Use TlbImport”,但这需要块library之类的内容在tssbx.idl没有(也不是它的家属)实现的IDL中。

什么是我最好的选择:

  1. 为C#找到一个等同于MIDL的工具,用于将.idl文件解析为.cs文件。
  2. 学习IDL(我一直无法找到好的指南来学习它)并用C#手写整篇文章。
  3. 使用提供的C文件编写一个帮助器dll,并将该调用放入我的C#dll中,用于我的.NET部件。
  4. 重新学习C ++,使用提供的.h和.c文件,并使用CLR进行.NET调用。
  5. 我没想过的其他一些选择。

2 个答案:

答案 0 :(得分:1)

我将此作为答案发布,因为评论时间过长

从我收集的内容中,在.NET中编写此类插件可能会在以后引发问题 - 尤其是在一个场景中,必须加载多个基于.NET的插件,并且两个(或更多)插件使用不同的.NET版本(在shell扩展的上下文中已经明确提到了这些问题 - 我只是从这种情况是我怀疑的依据......)。

至于您的选项IDL itseld无法实现任何内容 - 它是接口描述语言

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

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

答案 1 :(得分:1)

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

将IDL转换为C#实际上并不复杂;在大多数情况下,它直接从IDL关键字映射到C#关键字和/或MarshalAs属性。我有一系列关于如何与tlbimp进行COM互操作的博客文章,包括how to read IDL上的一个。我不知道有任何工具,特别是那些做得很好的工具,但如果它是Windows SDK的一部分,你应该先检查pinvoke.net,以防其他人为你做这件事。

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

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