.NET下调用COM组件

最近想要用到IFileDialog来实现选择打开文件夹的功能,这一功能是基于COM组件的。当然现在已经已有对其的.NET封装,使用广泛的是 Windows-API-Code-Pack,但是这一项目是面向.NET Framework,不是.NET Core的。同时加上我希望我了解COM,所以自己尝试实现了一下。

首先第一步是要创建COM对象,在.NET下可以用Activator.CreateInstance配合Type.GetTypeFromCLSID来创建,当然可以P/Invoke调用CoCreateInstance来创建。最后的效果都是一样的,创建出了一个System. __ComObject这一类型的特殊对象。

下一步就是要调用对象的方法了。调用COM对象的方法都是针对接口来调用,首先所有的对象都实现了IUnknown接口,这一接口实现了QueryInterfaceAddRefRelease 这三个基本的方法,不过,由于.NET的封装,我们并不能直接调用这三个方法,需要时只能通过Marshal类来间接调用。不过这样也有好处,可以用简单的as语句来代替复杂的QueryInterface。所以只要我们需要定义出COM接口对应的托管定义,然后使用as即可。同时注意正确调用AddRefRelease即可。

关于接口的定义,首先需要三个Attribute:ComImportGuidInterfaceTypeGuid的参数就是这一接口的IIDInterface的参数为ComInterfaceType.InterfaceIsIUnknown。还需要保证,方法的定义顺序必须严格一致,不能缺漏(可以漏掉后面的,不能在中间缺前面有遗漏),因为调用时是根据方法顺序进行调用。另外COM组件的接口是可以继承的,但是,这里的继承,只继承定义不继承实现。所以在.NET中,需要手工实现继承,即要把父接口的方法定义拷贝一份到子接口。

COM组件调用大概就是这样,类似于P/Invoke,但是多了一些新的东西。

Posted in C#

发表评论

此站点使用Akismet来减少垃圾评论。了解我们如何处理您的评论数据