在Web中使用Windows控件

版权声明:本文为博主原创文章,未经博主允许不得转载。

目录(?)[+]

  1. 将Net控件转化为ActiveX控件
    1. 1GUID
    2. 2实现IObjectSafety接口
    3. 3程序集设定
  2. 制作安装程序
  3. Web集成

最近做的一个Web版的视频会议项目,需要在网页中播放来自远程摄像头采集的实时视频,我们已经有了播放远程实时视频的使用C#编写的windows控件,如何将其嵌入到网页中去了?这需要使用一种古老的技术,ActiveX。

1.将.Net控件转化为ActiveX控件

首先要做的就是将我们的windows视频播放控件转化为ActiveX控件。先看看我们视频播放控件的定义,其基于OMCS实现,相当简单:

[csharp] view plain copy print?

  1. public partial class CameraVideoPlayer : UserControl
  2. {
  3. private IMultimediaManager multimediaManager;
  4. public CameraVideoPlayer()
  5. {
  6. InitializeComponent();
  7. }
  8. public void Test()
  9. {
  10. Random ran = new Random();
  11. string userID = "bb" + ran.Next(1001,9999).ToString();
  12. this.Initialize("223.4.*.*", 9900, userID, "aa01");
  13. }
  14. public void Initialize(string serverIP, int port, string userID, string targetUserID)
  15. {
  16. try
  17. {
  18. this.multimediaManager = MultimediaManagerFactory.GetSingleton();
  19. this.multimediaManager.Initialize(userID, "", serverIP, port);
  20. this.cameraConnector1.BeginConnect(targetUserID);
  21. }
  22. catch (Exception ee)
  23. {
  24. MessageBox.Show(ee.Message);
  25. }
  26. }

 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的特性:

[csharp] view plain copy print?

  1. [Guid("D9906B42-56B3-4B94-B4F9-A767194A382F")]
  2. public partial class CameraVideoPlayer : UserControl

    [Guid("D9906B42-56B3-4B94-B4F9-A767194A382F")]
    public partial class CameraVideoPlayer : UserControl

(2)实现IObjectSafety接口

当ActiveX控件在浏览器中调用的时候,往往会出现警告框,提示不安全的控件正在运行。这是由浏览器安全策略所限定的,控件通过实现IObjectSafety接口以向浏览器表明自己是合法的。在项目中增加IObjectSafety接口的定义:

[csharp] view plain copy print?

  1. [Guid("CB5BDC81-93C1-11CF-8F20-00805F2CD064"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
  2. public interface IObjectSafety
  3. {
  4. void GetInterfacceSafyOptions(System.Int32 riid,out System.Int32 pdwSupportedOptions,out System.Int32 pdwEnabledOptions);
  5. void SetInterfaceSafetyOptions(System.Int32 riid, System.Int32 dwOptionsSetMask, System.Int32 dwEnabledOptions);
  6. }

    [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实现这个接口:

[csharp] view plain copy print?

  1. [Guid("D9906B42-56B3-4B94-B4F9-A767194A382F")]
  2. public partial class CameraVideoPlayer : UserControl, IObjectSafety
  3. {
  4. private IMultimediaManager multimediaManager;
  5. public CameraVideoPlayer()
  6. {
  7. InitializeComponent();
  8. }
  9. public void Test()
  10. {
  11. Random ran = new Random();
  12. string userID = "bb" + ran.Next(1001,9999).ToString();
  13. this.Initialize("223.4.180.116", 9900, userID, "aa01");
  14. }
  15. public void Initialize(string serverIP, int port, string userID, string targetUserID)
  16. {
  17. try
  18. {
  19. this.multimediaManager = MultimediaManagerFactory.GetSingleton();
  20. this.multimediaManager.Initialize(userID, "", serverIP, port);
  21. this.cameraConnector1.BeginConnect(targetUserID);
  22. }
  23. catch (Exception ee)
  24. {
  25. MessageBox.Show(ee.Message);
  26. }
  27. }
  28. public void GetInterfacceSafyOptions(int riid, out int pdwSupportedOptions, out int pdwEnabledOptions)
  29. {
  30. pdwSupportedOptions = 1;
  31. pdwEnabledOptions = 2;
  32. }
  33. public void SetInterfaceSafetyOptions(int riid, int dwOptionsSetMask, int dwEnabledOptions)
  34. {
  35. }
  36. }

    [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特性。如下所示:

[csharp] view plain copy print?

  1. // 将 ComVisible 设置为 false 使此程序集中的类型
  2. // 对 COM 组件不可见。如果需要从 COM 访问此程序集中的类型,
  3. // 则将该类型上的 ComVisible 特性设置为 true。
  4. [assembly: ComVisible(true)]
  5. [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] view plain copy print?

  1. <html xmlns="http://www.w3.org/1999/xhtml" >
  2. <head>
  3. <title>摄像头视频播放器测试</title>
  4. </head>
  5. <body>
  6. <form id="form1">
  7. <table>
  8. <tr>
  9. <td align="center">
  10. <object id="cameraVideoPlayer"
  11. <strong> classid="clsid:{D9906B42-56B3-4B94-B4F9-A767194A382F}" codebase="setup.exe"</strong> width="320" height="240">
  12. </object>
  13. </td>
  14. </tr>
  15. <tr>
  16. <td align="center">
  17. <input type=button id="Button1" value="连接摄像头" onclick="javascript:doTest()"/>
  18. </td>
  19. </tr>
  20. </table>
  21. <script type="text/javascript">
  22. function doTest()
  23. {
  24. var obj = document.getElementById("cameraVideoPlayer");
  25. obj.Test();
  26. }
  27. </script>
  28. </form>
  29. </body>
  30. </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控件一样正常运行了:)

时间: 2024-09-29 19:43:00

在Web中使用Windows控件的相关文章

在web中使用windows控件,实现摄像头功能

最近做的一个Web版的视频会议项目,需要在网页中播放来自远程摄像头采集的实时视频,我们已经有了播放远程实时视频的使用C#编写的windows控件,如何将其嵌入到网页中去了?这需要使用一种古老的技术,ActiveX. 1.将.Net控件转化为ActiveX控件 首先要做的就是将我们的windows视频播放控件转化为ActiveX控件.先看看我们视频播放控件的定义,其基于OMCS实现,相当简单: [csharp] view plain copy public partial class Camera

在Web中如何使用Windows控件(ActiveX)[转]

最近做的一个Web项目,需要在网页中播放摄像头采集的实时视频,我们已经有了播放视频的使用C#编写的windows控件,如何将其嵌入到网页中去了?这需要使用一种古老的技术,ActiveX. 1.将.Net控件转化为ActiveX控件 首先要做的就是将我们的windows视频播放控件转化为ActiveX控件.先看看我们视频播放控件的定义,其基于OMCS实现,相当简单: public partial class CameraVideoPlayer : UserControl { private IMu

在D语言中如何调用Windows中的COM控件

Windows中COM组件是Windows中重要组成部分,可以注册成系统公共组件,也可以不注册直接调用.在D语言中调用COM组件前,我们需要了解COM组件.COM组件都有一个公共的接口,使用IDL语言编写,使用mild.exe编译器编译后生成tlb格式文件,通常叫做类型库,在生成COM组件的DLL时,会把这个文件放在DLL的资源文件中,资源名称叫做TYPELIB        要调用COM组件,先需要知道COM组件的接口,因此可以先从dll中把类型库导出成IDL接口文件,再把IDL接口文件转化为

C# windows服务:C#windows服务中的Timer控件的使用

C# windows服务程序中的Timer控件的使用问题是如何解决的呢? 今天研究了下C# windows服务程序中的Timer控件的使用的写法. 我们在建立一个C# windows服务程序后,要用到计时器的话一般都会想到Timer控件,于是到工具器把Timer控件拉过来,双击写事件,设置时间 但服务一跑起来,唉,怎么回事,时间到了怎么没有执行事件呢? 后来,我找很多资料才知道,这个Timer控件是winForm下的,不能用在C# windows服务程序中. 怎么办呢....... 打开"工具箱

利用ArcGIS Engine、VS .NET和Windows控件开发GIS应用

原文:利用ArcGIS Engine.VS .NET和Windows控件开发GIS应用 此过程说明适合那些使用.NET建立和部署应用的开发者,它描述了使用ArcGIS控件建立和部署应用的方法和步骤. 你可以在下面的目录下找到相应的样例程序: <安装目录>\DeveloperKit\Samples\Developer_Guide_Scenarios\ ArcGIS_Engine\Building_an_ArcGIS_Control_Application\Map_Viewer 注:ArcGIS样

在代码中动态创建控件无法保存状态的问题

在网上找了点资料,算是明白了,这是我觉得有帮助的文章: 原文:http://blog.csdn.net/keleloveni/archive/2007/03/15/1530300.aspx 引文: 今天偶然看到有篇文章谈到了相关的问题,终于又解决了一个自己不是很明白的东西. 页面生命周期中的第一个阶段是实例化,在这个阶段中,自动生成的类会根据页面的 HTML 部分中定义的静态控件构建控件层次结构.构造控件层次结构时,声明性语法中指定的值会赋给添加的每个控件的属性.实例化之后是初始化阶段,在这个阶

WPF中嵌入WinForm中的webbrowser控件

原文:WPF中嵌入WinForm中的webbrowser控件 使用VS2008创建WPF应用程序,需使用webbrowser.从工具箱中添加WPF组件中的webbrowser发现其中有很多属性事件不能使用.决定还是使用WinForm中的webbrowser.要想在WPF中使用WinForm控件,查看MSDN,需经过以下步骤. 创建名为 HostingWfInWpf 的 WPF 应用程序项目. 在解决方案资源管理器中,添加一个对名为 WindowsFormsIntegration.dll 的 Wi

在 UWP 中实现 Expander 控件

WPF 中的 Expander 控件在 Windows 10 SDK 中并不提供,本文主要说明,如何在 UWP 中创建这样一个控件.其效果如下图: 首先,分析该控件需要的一些特性,它应该至少包括如下三个属性: Content: 最重要的属性,设置该属性,可以使 Expander 控件显示其内容: Header: 控件的 Header: IsExpand: 当前是否展开. 接下来是定义其 UI,在这里使用 Grid,添加两行,一行显示 Header,一行显示 Content,当 IsExpand

ASP.NET AJAX入门系列(11):在多个UpdatePanle中使用Timer控件

本文将使用Timer控件更新两个UpdatePanel控件,Timer控件将放在UpdatePanel控件的外面,并将它配置为UpdatePanel的触发器,翻译自官方文档. 主要内容 在多个UpdatePanel中使用Timer控件 1.添加一个新页面并切换到设计视图. 2.如果页面没有包含ScriptManager控件,在工具箱中的AJAX Extensions标签下双击ScriptManager控件添加到页面中. 3.双击Timer控件添加到Web页面中.Timer控件可以作为Update