背景
最近需要做web实时播放摄像头视频的管理网站,而设备提供的接口则是需要提供控件句柄,java语言获取控件句柄不太会,只好考虑利用C#将控件做成activeX嵌入网页中。
开发步骤
1.利用vs2010创建一个windows窗体控件库,命名为VideoPlay;
2.在窗体控件中添加一个pictureBox控件及两个按钮;
3.在AssemblyInfo.cs中引用System.Security命名空间,并添加一句:[assembly : AllowPartiallyTrustedCallers()]
4.创建GUID
ActiveX控件首先是COM组件,COM组件有唯一的GUID。后面我们可以看到,在Web中,需要通过GUID定位并加载已经注册的ActiveX控件。
如果使用的是VS2010,工具菜单下有个“创建GUID”菜单,点击它可以创建一个新的GUID,然后把其复制作为CameraVideoPlayer的特性:
[Guid("2A80B21A-9E7C-40B3-88DA-CF98A6A34B3D")]
public partial class VideoPlay: UserControl
5. 实现IObjectSafety接口
当ActiveX控件在浏览器中调用的时候,往往会出现警告框,提示不安全的控件正在运行。这是由浏览器安全策略所限定的,控件通过实现IObjectSafety接口以向浏览器表明自己是合法的。在项目中增加IObjectSafety接口的定义:
[Guid("CB5BDC81-93C1-11CF-8F20-00805F2CD064"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
public interface IObjectSafety
{
void GetInterfacceSafyOptions(System.Int32 riid,out System.Int32 pdwSupportedOptions,out System.Int32 pdwEnabledOptions);
void SetInterfaceSafetyOptions(System.Int32 riid, System.Int32 dwOptionsSetMask, System.Int32 dwEnabledOptions);
}
并让VideoPlay实现这个接口
[Guid("2A80B21A-9E7C-40B3-88DA-CF98A6A34B3D")]
public partial class VideoPlay: UserControl, IObjectSafety
{
public VideoPlay()
{
InitializeComponent();
}
public void GetInterfacceSafyOptions(int riid, out int pdwSupportedOptions, out int pdwEnabledOptions)
{
pdwSupportedOptions = 1;
pdwEnabledOptions = 2;
}
public void SetInterfaceSafetyOptions(int riid, int dwOptionsSetMask, int dwEnabledOptions)
{
}
}
IObjectSafety接口的两个方法的实现都可以采用上面的代码来做。
6.程序集设定
接下来,我们需要对控件的程序集(OMCS_ActiveX)做一个设置,以表明其将作为一个COM组件使用。打开AssemblyInfo.cs文件,首先将ComVisible特性设置为true。其次,增加AllowPartiallyTrustedCallers特性。如下所示:
// 将 ComVisible 设置为 false 使此程序集中的类型
// 对 COM 组件不可见。如果需要从 COM 访问此程序集中的类型,
// 则将该类型上的 ComVisible 特性设置为 true。
[assembly: ComVisible(true)]
[assembly: AllowPartiallyTrustedCallers()]
最后,在项目属性的“生成”页中,将“为COM互操作注册”的CheckBox勾上。
7.制作安装程序
在当前解决方案中添加一个新的安装项目;
将上面的项目的主输出导入到安装项目的“应用程序文件夹”下面;
修改主输出的文件安装属性中的Register项为vsdrpCOM;
编译安装项目,将会生成两个文件setup.exe、Setup1.msi。将它们拷贝到网站虚拟目录的根目录下。
8.Web集成
现在我们写一个最简单的HTML来试试加载视频播放的ActiveX控件:
<html xmlns="http://www.w3.org/1999/xhtml" >
<head>
<title></title>
</head>
<body>
<form id="form1">
<table>
<tr>
<td align="center">
<object id="videoplayer"
classid="clsid:{2A80B21A-9E7C-40B3-88DA-CF98A6A34B3D}" codebase="VideoPlaySetup.msi" width="500" height="600">
</object>
</td>
</tr>
</table>
</form>
</body>
</html>
这个Classid就是我们在VideoPlay.cs的Guid里的序列号,浏览器是通过GUID来定位ActiveX控件的,如果本机不存在目标ActiveX控件,则自动下载codebase属性指示的安装程序进行安装。
将HTML文件部署好后,可以打开网页,需要允许浏览器加载activeX。
9.cab文件制作
当然,也可做成cab文件嵌入网页,需要如下工具:
cabarc.exe:微软提供的cab打包工具
VideoPlaySetup.msi: 项目生成的部署安装文件
install.inf : 需要跟ActiveXSetup.msi打包在一起的文件
build.bat: 打包的批处理命令
其中,install.inf文件内容如下:
[version]
signature="$CHICAGO$"
AdvancedINF=2.0
[Setup Hooks]
hook1=hook1
[hook1]
run=msiexec.exe /i "%EXTRACT_DIR%\VideoPlaySetup.msi" /qn
build.bat内容如下:
"cabarc.exe" n VideoPlaySetup.cab VideoPlaySetup.msi install.inf
运行一下bat就可以生成一个cab文件,在网页中,将原来的msi文件换成cab文件即可。
<html xmlns="http://www.w3.org/1999/xhtml" >
<head>
<title></title>
</head>
<body>
<form id="form1">
<table>
<tr>
<td align="center">
<object id="videoplayer"
classid="clsid:{2A80B21A-9E7C-40B3-88DA-CF98A6A34B3D}" codebase="VideoPlaySetup.cab" width="500" height="600">
</object>
</td>
</tr>
</table>
</form>
</body>
</html>
以上就是我的制作过程,如有不正确之处,还望指正。
参考文章
http://www.it165.net/pro/html/201209/3743.html
http://www.cnblogs.com/li-peng/p/3455247.html
http://www.cnblogs.com/qishichang/archive/2010/02/28/1675213.html
Q&A
1.如果编译时,提示你权限不够(Windows 7 UAC),需要以管理员运行Visual Studio。
2.如果编译时,The assembly could not be converted to a type library. Type library exporter
encountered an error while processing 'xxxxxx'. Error: 找不到元素.
在Relase 下进行编译。
3.如果其他计算机通过IE查看该网页,acitveX没有安装,网页上只有一个红叉,则有可能是对应版本的.netframework没有安装。