在Web中使用Windows控件
版权声明:本文为博主原创文章,未经博主允许不得转载。
最近做的一个Web版的视频会议项目,需要在网页中播放来自远程摄像头采集的实时视频,我们已经有了播放远程实时视频的使用C#编写的windows控件,如何将其嵌入到网页中去了?这需要使用一种古老的技术,ActiveX。
1.将.Net控件转化为ActiveX控件
首先要做的就是将我们的windows视频播放控件转化为ActiveX控件。先看看我们视频播放控件的定义,其基于OMCS实现,相当简单:
- public partial class CameraVideoPlayer : UserControl
- {
- private IMultimediaManager multimediaManager;
- public CameraVideoPlayer()
- {
- InitializeComponent();
- }
- public void Test()
- {
- Random ran = new Random();
- string userID = "bb" + ran.Next(1001,9999).ToString();
- this.Initialize("223.4.*.*", 9900, userID, "aa01");
- }
- public void Initialize(string serverIP, int port, string userID, string targetUserID)
- {
- try
- {
- this.multimediaManager = MultimediaManagerFactory.GetSingleton();
- this.multimediaManager.Initialize(userID, "", serverIP, port);
- this.cameraConnector1.BeginConnect(targetUserID);
- }
- catch (Exception ee)
- {
- MessageBox.Show(ee.Message);
- }
- }
- }

public partial class CameraVideoPlayer : UserControl
{
private IMultimediaManager multimediaManager;
public CameraVideoPlayer()
{
InitializeComponent();
} public void Test()
{
Random ran = new Random();
string userID = "bb" + ran.Next(1001,9999).ToString();
this.Initialize("223.4.*.*", 9900, userID, "aa01");
} public void Initialize(string serverIP, int port, string userID, string targetUserID)
{
try
{
this.multimediaManager = MultimediaManagerFactory.GetSingleton();
this.multimediaManager.Initialize(userID, "", serverIP, port);
this.cameraConnector1.BeginConnect(targetUserID);
}
catch (Exception ee)
{
MessageBox.Show(ee.Message);
} }
}
当调用其Initialize方法时,将连接到目标用户的摄像头,并在其内含的cameraConnector1控件上播放视频。这个控件在Windows Form应用程序中工作良好,现在我们一步步来将其转换为ActiveX控件。
(1)GUID
ActiveX控件首先是COM组件,COM组件有唯一的GUID。后面我们可以看到,在Web中,需要通过GUID定位并加载已经注册的ActiveX控件。
如果使用的是VS2010,工具菜单下有个“创建GUID”菜单,点击它可以创建一个新的GUID,然后把其复制作为CameraVideoPlayer的特性:
- [Guid("D9906B42-56B3-4B94-B4F9-A767194A382F")]
- public partial class CameraVideoPlayer : UserControl

[Guid("D9906B42-56B3-4B94-B4F9-A767194A382F")]
public partial class CameraVideoPlayer : UserControl
(2)实现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);
- }

[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);
}
并让CameraVideoPlayer实现这个接口:
- [Guid("D9906B42-56B3-4B94-B4F9-A767194A382F")]
- public partial class CameraVideoPlayer : UserControl, IObjectSafety
- {
- private IMultimediaManager multimediaManager;
- public CameraVideoPlayer()
- {
- InitializeComponent();
- }
- public void Test()
- {
- Random ran = new Random();
- string userID = "bb" + ran.Next(1001,9999).ToString();
- this.Initialize("223.4.180.116", 9900, userID, "aa01");
- }
- public void Initialize(string serverIP, int port, string userID, string targetUserID)
- {
- try
- {
- this.multimediaManager = MultimediaManagerFactory.GetSingleton();
- this.multimediaManager.Initialize(userID, "", serverIP, port);
- this.cameraConnector1.BeginConnect(targetUserID);
- }
- catch (Exception ee)
- {
- MessageBox.Show(ee.Message);
- }
- }
- public void GetInterfacceSafyOptions(int riid, out int pdwSupportedOptions, out int pdwEnabledOptions)
- {
- pdwSupportedOptions = 1;
- pdwEnabledOptions = 2;
- }
- public void SetInterfaceSafetyOptions(int riid, int dwOptionsSetMask, int dwEnabledOptions)
- {
- }
- }

[Guid("D9906B42-56B3-4B94-B4F9-A767194A382F")]
public partial class CameraVideoPlayer : UserControl, IObjectSafety
{
private IMultimediaManager multimediaManager;
public CameraVideoPlayer()
{
InitializeComponent();
}
public void Test()
{
Random ran = new Random();
string userID = "bb" + ran.Next(1001,9999).ToString();
this.Initialize("223.4.180.116", 9900, userID, "aa01");
}
public void Initialize(string serverIP, int port, string userID, string targetUserID)
{
try
{
this.multimediaManager = MultimediaManagerFactory.GetSingleton();
this.multimediaManager.Initialize(userID, "", serverIP, port);
this.cameraConnector1.BeginConnect(targetUserID);
}
catch (Exception ee)
{
MessageBox.Show(ee.Message);
}
}
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接口的两个方法的实现都可以采用上面的代码来做。
(3)程序集设定
接下来,我们需要对控件的程序集(OMCS_ActiveX)做一个设置,以表明其将作为一个COM组件使用。打开AssemblyInfo.cs文件,首先将ComVisible特性设置为true。其次,增加AllowPartiallyTrustedCallers特性。如下所示:
- // 将 ComVisible 设置为 false 使此程序集中的类型
- // 对 COM 组件不可见。如果需要从 COM 访问此程序集中的类型,
- // 则将该类型上的 ComVisible 特性设置为 true。
- [assembly: ComVisible(true)]
- [assembly: AllowPartiallyTrustedCallers()]

// 将 ComVisible 设置为 false 使此程序集中的类型
// 对 COM 组件不可见。如果需要从 COM 访问此程序集中的类型,
// 则将该类型上的 ComVisible 特性设置为 true。
[assembly: ComVisible(true)]
[assembly: AllowPartiallyTrustedCallers()]
最后,在项目属性的“生成”页中,将“为COM互操作注册”的CheckBox勾上。

这样,编译生成的产物中除了OMCS_ActiveX.dll外,还有OMCS_ActiveX.tlb(COM用到的类型库文件)。
2.制作安装程序
转化后的CameraVideoPlayer ActiveX控件会被部署在IIS服务器上,用户第一次打开网页时,在用户的机器上是不存在这个控件的,所以,需要下载安装并在用户的机器上注册该ActiveX控件。这些可以通过VS自带的制作安装程序的功能来实现,也相当简单。
(1)在当前解决方案中添加一个新的安装项目。
(2)将OMCS_ActiveX项目的主输出导入到安装项目的“应用程序文件夹”下面。

(3)修改主输出的文件安装属性中的Register项为vsdrpCOM。
(4)设置安装项目的项目属性,主要是“安装URL”项,要设置为部署时地址。

(5)如果需要,将“系统必备”中的一些项目勾上或去掉。
(6)编译安装项目,将会生成两个文件setup.exe、Setup1.msi。将它们拷贝到网站虚拟目录的根目录下。
3.Web集成
现在我们写一个最简单的HTML来试试加载视频播放的ActiveX控件CameraVideoPlayer。如下所示:
- <html xmlns="http://www.w3.org/1999/xhtml" >
- <head>
- <title>摄像头视频播放器测试</title>
- </head>
- <body>
- <form id="form1">
- <table>
- <tr>
- <td align="center">
- <object id="cameraVideoPlayer"
- <strong> classid="clsid:{D9906B42-56B3-4B94-B4F9-A767194A382F}" codebase="setup.exe"</strong> width="320" height="240">
- </object>
- </td>
- </tr>
- <tr>
- <td align="center">
- <input type=button id="Button1" value="连接摄像头" onclick="javascript:doTest()"/>
- </td>
- </tr>
- </table>
- <script type="text/javascript">
- function doTest()
- {
- var obj = document.getElementById("cameraVideoPlayer");
- obj.Test();
- }
- </script>
- </form>
- </body>
- </html>

<html xmlns="http://www.w3.org/1999/xhtml" >
<head>
<title>摄像头视频播放器测试</title>
</head>
<body>
<form id="form1">
<table>
<tr>
<td align="center">
<object id="cameraVideoPlayer"
classid="clsid:{D9906B42-56B3-4B94-B4F9-A767194A382F}" codebase="setup.exe" width="320" height="240">
</object>
</td>
</tr>
<tr>
<td align="center">
<input type=button id="Button1" value="连接摄像头" onclick="javascript:doTest()"/>
</td>
</tr>
</table> <script type="text/javascript">
function doTest()
{
var obj = document.getElementById("cameraVideoPlayer");
obj.Test();
}
</script>
</form>
</body>
</html>
注意加粗的部分,说明了两点:
(1)浏览器是通过GUID来定位ActiveX控件的。
(2)如果本机不存在目标ActiveX控件,则自动下载codebase属性指示的安装程序进行安装。
将HTML文件部署好后,第一次打开网页,如下所示:

运行安装,完成后,页面会刷新,并可以看到ActiveX控件已经成功加载进来了。然后,点击“连接摄像头”按钮,测试一下ActiveX控件是否可以显示远程摄像头采集的视频,如下所示:

这样,嵌入到网页中的ActiveX控件就像普通的windows控件一样正常运行了:)
在Web中使用Windows控件的更多相关文章
- 在web中使用windows控件,实现摄像头功能
最近做的一个Web版的视频会议项目,需要在网页中播放来自远程摄像头采集的实时视频,我们已经有了播放远程实时视频的使用C#编写的windows控件,如何将其嵌入到网页中去了?这需要使用一种古老的技术,A ...
- HTML5 Web app开发工具Kendo UI Web中Grid网格控件的使用
Kendo UI Web中的Grid控件不仅可以显示数据,并对数据提供了丰富的支持,包括分页.排序.分组.选择等,同时还有着大量的配置选项.使用Kendo DataSource组件,可以绑定到本地的J ...
- 在Web中如何使用Windows控件(ActiveX)[转]
最近做的一个Web项目,需要在网页中播放摄像头采集的实时视频,我们已经有了播放视频的使用C#编写的windows控件,如何将其嵌入到网页中去了?这需要使用一种古老的技术,ActiveX. 1.将.Ne ...
- 向ArcGIS的ToolBarControl中添加任意的windows控件的方法
概要:在使用ArcEngine开发中,给ToolbarControl添加按钮形式的命令项相信大家都很熟悉了,因为网上的例子很多.但这种使用click调用功能的方式只能满足大部分用户在体验方面的需求,除 ...
- C# windows服务:C#windows服务中的Timer控件的使用
C# windows服务程序中的Timer控件的使用问题是如何解决的呢? 今天和同事一起研究了下C# windows服务程序中的Timer控件的使用的写法. 我们在建立一个C# windows服务程序 ...
- 利用ArcGIS Engine、VS .NET和Windows控件开发GIS应用
Dixon 原文 用ArcGIS Engine.VS .NET和Windows控件开发GIS应用 此过程说明适合那些使用.NET建立和部署应用的开发者,它描述了使用ArcGIS控件建立和部署 ...
- Ti IPNC Web网页之ActiveX控件
Ti IPNC Web网页之ActiveX控件 本篇介绍关于TI IPNC网页中播放器相关的东西. gStudio工程中添加播放器并控制播放器 打开IPNC网页时首先会自动下载ActiveX控件并安装 ...
- WEB页面常用基本控件测试用例
一.树控件的测试外观操作 1)项目中的所有树是否风格一致 2)树结构的默认状态是怎样的.比如默认树是否是展开,是展开几级? 是否有默认的焦点? 默认值是什么?展开的节点图标和颜色? 2.执行操作 1 ...
- 怎样在不对控件类型进行硬编码的情况下在 C#vs 中动态添加控件
文章ID: 815780 最近更新: 2004-1-12 这篇文章中的信息适用于: Microsoft Visual C# .NET 2003 标准版 Microsoft Visual C# .NET ...
随机推荐
- 透过代码理解python的静态方法、类方法与实例方法
话不多说,直接上程序: a = 111 class A(object): a = 1 def f_instance(self): print self.a @staticmetho ...
- sublime text 2 ubuntu安装及插件管理
参考 dudumao 1.下载Sublime Text2官网下载地址:http://www.sublimetext.com 2.安装Sublime Text2解压即可使用 $ sudo tar -jx ...
- Android之QQ新用户注册界面1
还没到睡觉时间所以再加了一个界面... 问题: 1.下拉列表(因为还没看到这里...) 2.标题栏显示问题 3.按钮的 Enable 设置 .......... 以下是代码: 布局 fragment_ ...
- 关于Kean博客的学习
由于我从事设计行业,使用Autocad进行绘图是一件单调但是拥有乐趣的工作. 大约在一年前,接触到了CAD的二次开发的内容,它使我感到新奇,并且决定花时间来研究相关的知识.这时我在网上浏览到了Kean ...
- String、Stringbuffer、StringBuilder的区别(转载)
最近学习到StringBuffer,心中有好些疑问,搜索了一些关于String,StringBuffer,StringBuilder的东西,现在整理一下. 关于这三个类在字符串处理中的位置不言而喻,那 ...
- 【转载】App.config/Web.config 中特殊字符的处理
写一个网站,遇到一个问题,发布以后,提示错误,但是即使打开错误提示(在web.config中打开),还是只提示错误,没提示什么地方错误,这让我知道了:是webconfig本身的错误,经过排除,是链接字 ...
- 架设lamp服务器后,发现未按照 Apache xsendfile模块,
今天在架设lamp服务器后,发现apache 未按照xsendfile模块,于是查找资料按照如下: 安装apache xsendfile模块yum install mod_xsendfile
- DOM编程 删除节点
需求: 为每个 li 节点添加一个 confirm(确认对话框): 确定要删除 xx 的信息吗?若确定, 则删除 1,获取li所有节点 var liNodes = document.getElemen ...
- 一触即发 App启动优化最佳实践
一触即发 App启动优化最佳实践 本文在 DiyCode 和 CSDN个人博客 同时首发,关注作者的 DiyCode帐号 或者 作者微博 可第一时间收到新文章推送. 文中的很多图都是Google性能优 ...
- 流编辑器-sed
sed 参数: 1.'s' 替换 sed 's/search-word/replace-word/' file-name 替换file-name文件中的search-word为replace-word ...