最近有一个项目需求,要把WPF开发的程序打包成COM组件供其他程序使用,WPF工程转COM并不困难,但有一些细节还是需要记录一下:

首先需要把应用程序转成类库:

需要注意当应用程序转换成类库后App.xaml就需要删除了,如果在App.xaml中做了启动控制或者全局资源字典,需要重新规划,如全局资源的加载方式,重复启动的判断等等。

还需要注意要把主窗体改成UserControl,否则组件会以窗口形式打开。

然后将类库打包成COM组件:

勾选”COM互操作类型”

将Properties下的AssemblyInfo的ComVisible设置为True

新建一个winform用户控件,并在用户控件上放置ElementHost控件,然后编写后台代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
[Guid("17F7AD9C-9814-4FB6-B0FA-B50F91FD8F3B")]
interface ITest
{
string SayHello();
}
[Guid("8F9CAB05-7E58-44B9-A8CF-FC6C02BF8EDB")]
public partial class MyHostUC : UserControl,ITest
{
public MyHostUC()
{
InitializeComponent();
MyWpfUC uc = new MyWpfUC(); //wpf用户控件
elementHost1.Child = uc;
}
public string SayHello()
{
return "hello";
}
}

其中凡是COM组件提供的对外接口都需要添加Guid的Attribute,Guid可用VS自带工具生成。

可以选择给组件添加强签名,在签名中勾选”为程序集签名”,新建,填写签名文件名称,根据需要选择给证书加密

需要注意如果给组件签名,那么要保证项目引用的所有dll都要有签名,否则无法完成注册,如果不选择签名,ie在调用COM组件时会根据安全等级提示或阻止加载。

最后注册并使用COM组件:

注册需要用VS命令行工具,管理员权限打开VS命令行提示工具,使用下面的命令:

regasm XXX.dll

这里可以看到与传统的COM组件regsvr32的注册方式不同,由于是使用.net开发,所以需要用regasm来注册。

注册完成后就可以在其它项目中使用,比如在IE中使用下面的方式:

1
2
3
4
5
6
7
8
9
10
11
12
<!DOCTYPE html>
<html lang="en" xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta charset="utf-8" />
<title></title>
</head>
<body>
<object classid="clsid:8F9CAB05-7E58-44B9-A8CF-FC6C02BF8EDB" id="test"
width="1280" height="800"></object>
</body>
</html>

注意这里面的classid不是com组件的id,而是接口入口的Guid.

如果是在其它winform或wpf项目中使用这个组件,首先添加这个组件:

在VS—工具—选择工具箱,进入.NetFrameWork 组件标签页,没错,不是COM组件,是.NetFrameWork组件,浏览编译并注册成功的dll,添加即可。

添加成功的控件在工具栏可以看到,还需要提醒一下,如果在wpf下使用这个控件,需要用WindowsFormsHost来做容器。