C#制做ActiveX浏览器插件.net

开发环境:VS2008javascript

第一步 建立项目html

新建一个项目,选择“Windows窗体控件库”,建立一个用户控件项目“ActiveXDemo”(注意,这里起名不能用中文,不然后面会出问题),里面有个用户控件类UserControl1.csjava

在类中写上你本身须要的业务逻辑代码,保存浏览器

第二步 设置项目属性安全

在AssemblyInfo.cs里添加[assembly: AllowPartiallyTrustedCallers()],须要引用using System.Security;命名空间函数

设置项目属性,右键项目——属性工具

选择“应用程序”,点开“程序集信息”ui

勾选“使程序集COM可见”,点“肯定”spa

而后选择“生成”,滚动拉倒底部,勾选“为COM互操做注册”插件

而后保存,从新编译项目,至此,此时的“ActiveXDemo.dll”就成了一个ActiveX控件

第三步 安装外部工具

安装外部工具“OLE/COM对象查看器”和“建立GUID”(已有这两款工具的能够忽略此步骤)

 

1.OLE/COM对象查看器

这款工具是用来查看ActiveX控件的,也就是验证你的项目有没有成为一个ActiveX控件

安装方法:点开VS顶部菜单栏“工具”——“外部工具”

而后,添加一个“OLE/COM对象查看器”,对应的命令程序通常放在C:\Program Files\Microsoft SDKs\Windows\v6.0A\Bin\OleView.Exe

点击“应用”,“肯定”,这就算是安装完成,再从新点开顶部的“工具”菜单看看,里面就有一项“OLE/COM对象查看器”

点击“OLE/COM对象查看器”,展开左侧的“.NET Category”

你会发现,这里面就有你刚刚建立的ActiveX控件

这就是OLE/COM对象查看器的做用

2.建立GUID

高版本的VS貌似都自带了这个工具,可是在有的低版本或者安装不完整好比Vs2008中不必定有这个工具,因此在没有的时候须要安装一下

安装方法同上,只不过命令程序的地址通常是C:\Program Files (x86)\Microsoft Visual Studio 9.0\Common7\Tools\guidgen.exe

此工具的用途在下面的步骤中会讲到

第四步 提升ActiveX插件的安全等级

IE怎么知道一个插件是脚本安全的?它是经过如下两个办法。

一是查询ActiveX组件是否实现了IObjectSafety接口,而且返回脚本安全;

二是查询ActiveX组件是否在注册表的Component  Category Manager里代表本身实现了CATID_SafeForInitializing和CATID_SafeForScripting。

这里咱们只说第一种实现IObjectSafety接口

首先,为控件类UserControl1添加一个GUID,这个编号将用于B/S系统的客户端调用时使用(可使用 工具-建立GUID 菜单建立一个GUID):

using System;
using System.Collections.Generic;
using System.Text;
using System.Windows.Forms;
using System.Runtime.InteropServices;

namespace ActiveXDemo
{
    [Guid("BB725724-65D6-4e71-AA11-DEDFAFE9248F"), ProgId("ActiveXDemo.UserControl1"), ComVisible(true)]
    public partial class UserControl1 : UserControl,IObjectSafety
    {

 注意,要引入System.Runtime.InteropServices;命名空间

其次,为了让ActiveX控件得到客户端的信任,控件类还须要实现一个名为“IObjectSafety”的接口,所以在项目中添加一个接口类IObjectSafety

直接将下列代码复制粘贴,不要做任何改动,尤为是GUID,都是固定的,不能改

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Runtime.InteropServices;

namespace ActiveXDemo
{
    [ComImport, GuidAttribute("CB5BDC81-93C1-11CF-8F20-00805F2CD064")]
    [InterfaceTypeAttribute(ComInterfaceType.InterfaceIsIUnknown)]
    public interface IObjectSafety
    {
        [PreserveSig]
        int GetInterfaceSafetyOptions(ref Guid riid, [MarshalAs(UnmanagedType.U4)] ref int pdwSupportedOptions, [MarshalAs(UnmanagedType.U4)] ref int pdwEnabledOptions);

        [PreserveSig()]
        int SetInterfaceSafetyOptions(ref Guid riid, [MarshalAs(UnmanagedType.U4)] int dwOptionSetMask, [MarshalAs(UnmanagedType.U4)] int dwEnabledOptions);
    }
}

 

一样,须要引入System.Runtime.InteropServices;命名空间

接着,在控件类UserControl1中实现IObjectSafety的接口

        #region IObjectSafety 成员

        private const string _IID_IDispatch = "{00020400-0000-0000-C000-000000000046}";
        private const string _IID_IDispatchEx = "{a6ef9860-c720-11d0-9337-00a0c90dcaa9}";
        private const string _IID_IPersistStorage = "{0000010A-0000-0000-C000-000000000046}";
        private const string _IID_IPersistStream = "{00000109-0000-0000-C000-000000000046}";
        private const string _IID_IPersistPropertyBag = "{37D84F60-42CB-11CE-8135-00AA004BB851}";

        private const int INTERFACESAFE_FOR_UNTRUSTED_CALLER = 0x00000001;
        private const int INTERFACESAFE_FOR_UNTRUSTED_DATA = 0x00000002;
        private const int S_OK = 0;
        private const int E_FAIL = unchecked((int)0x80004005);
        private const int E_NOINTERFACE = unchecked((int)0x80004002);

        private bool _fSafeForScripting = true;
        private bool _fSafeForInitializing = true;

        public int GetInterfaceSafetyOptions(ref Guid riid, ref int pdwSupportedOptions, ref int pdwEnabledOptions)
        {
            int Rslt = E_FAIL;

            string strGUID = riid.ToString("B");
            pdwSupportedOptions = INTERFACESAFE_FOR_UNTRUSTED_CALLER | INTERFACESAFE_FOR_UNTRUSTED_DATA;
            switch (strGUID)
            {
                case _IID_IDispatch:
                case _IID_IDispatchEx:
                    Rslt = S_OK;
                    pdwEnabledOptions = 0;
                    if (_fSafeForScripting == true)
                        pdwEnabledOptions = INTERFACESAFE_FOR_UNTRUSTED_CALLER;
                    break;
                case _IID_IPersistStorage:
                case _IID_IPersistStream:
                case _IID_IPersistPropertyBag:
                    Rslt = S_OK;
                    pdwEnabledOptions = 0;
                    if (_fSafeForInitializing == true)
                        pdwEnabledOptions = INTERFACESAFE_FOR_UNTRUSTED_DATA;
                    break;
                default:
                    Rslt = E_NOINTERFACE;
                    break;
            }

            return Rslt;
        }

        public int SetInterfaceSafetyOptions(ref Guid riid, int dwOptionSetMask, int dwEnabledOptions)
        {
            int Rslt = E_FAIL;
            string strGUID = riid.ToString("B");
            switch (strGUID)
            {
                case _IID_IDispatch:
                case _IID_IDispatchEx:
                    if (((dwEnabledOptions & dwOptionSetMask) == INTERFACESAFE_FOR_UNTRUSTED_CALLER) && (_fSafeForScripting == true))
                        Rslt = S_OK;
                    break;
                case _IID_IPersistStorage:
                case _IID_IPersistStream:
                case _IID_IPersistPropertyBag:
                    if (((dwEnabledOptions & dwOptionSetMask) == INTERFACESAFE_FOR_UNTRUSTED_DATA) && (_fSafeForInitializing == true))
                        Rslt = S_OK;
                    break;
                default:
                    Rslt = E_NOINTERFACE;
                    break;
            }

            return Rslt;
        }

        #endregion

 这些代码也是固定的,不能改动,直接复制粘贴就好了

 第五步 制做成安装文件

在原项目解决方案中新建一个安装项目,在VS2008中,是这样操做的

新建项目——其余项目类型——安装和部署——安装项目

注意,这里下方“解决方案”这里要选择“添入解决方案

而后,右键安装项目——添加——项目输出

将咱们的项目ActiveXDemo设为主输出

点肯定,而后在主输出文件上右键——属性

将Register属性设为vsdrpCOM

从新编译安装项目,打开安装项目所在目录

至此,ActiveX浏览器插件的安装包就制做好了,双击setup.exe文件或ActiveXDemoSetup.msi文件能够将浏览器插件安装到你的电脑

第六步 使用ActiveX插件

新建一个Web项目或者一个Html文件,在须要使用浏览器插件的页面上加入如下代码:

<html xmlns="http://www.w3.org/1999/xhtml" >
<head runat="server">
    <title>无标题页</title>
</head>
<body>
<object id="csharpActiveX" classid="clsid:BB725724-65D6-4e71-AA11-DEDFAFE9248F" width="100%" height="150"></object>

    <form id="form1" runat="server">
    <div>
    <input type='button' onclick='csharpActiveX.Test()' value='我是按钮'/>
    </div>
    </form>
</body>

 其中,重点是object标签里的classid属性,属性里面的GUID对应的就是第四步中指定的GUID

直接使用object定义的id属性就能够调用UserControl1类中的方法,是否是很方便?

为了更方便直观的看出插件有没有正常加载,能够再加入一些检测代码,以下:

<body>
<object id="csharpActiveX" classid="clsid:BB725724-65D6-4e71-AA11-DEDFAFE9248F" width="100%" height="150"></object>

    <form id="form1" runat="server">
    <div>
    <input type='button' onclick='csharpActiveX.Test()' value='我是按钮'/>
    </div>
    </form>
</body>
<script type="text/javascript">
    var objCard = document.getElementById("csharpActiveX");

    if (objCard.object==null) {
        alert("csharpActiveX插件未安装!");
    }
    else{
        alert("已检测到csharpActiveX插件!");
    }
</script>
</html>

 而后,因为只有IE支持ActiveX浏览器插件,因此在IE浏览器中打开这个页面,看一下效果

这时,不放心的话,能够再检查我们的ActiveX插件究竟有没有安装上

点开工具栏“工具”——“管理加载项”

能够看到其中有一项ActiveXDemo.UserControl1,这就是咱们安装上去的浏览器插件

 

第七步 ActiveX插件调用页面Js

这里,主要须要引入一个程序集叫Microsoft.mshtml.dll,它在系统文件夹里C:\Program Files (x86)\Microsoft.NET\Primary Interop Assemblies

引入后,开始在插件项目里写上注册Js函数相关的代码,以下

        private IHTMLWindow2 temphtml = null;
        private string functionstr = "";

        public void RegJs(object objWinJs, string funcJs)
        {
            temphtml = (IHTMLWindow2)objWinJs;
            if (temphtml != null && !string.IsNullOrEmpty(funcJs))
            {
                functionstr = funcJs;
            }
            else
            {
                temphtml = null;
                functionstr = "";
                MessageBox.Show("注册ActiveX插件回调脚本失败");
            }
        }    

以及,执行页面Js函数的代码

        private void ShowResult(object s, EventArgs e)
        {
            try
            {
                //必需要阻塞线程一段时间,以避免在交易超时的状况下,因为read太快致使读取不完整
                System.Threading.Thread.Sleep(500);
                string txt = serialPort.ReadExisting();

                temphtml.execScript("var msgActiveX='" + txt+"';", "JScript");
                temphtml.execScript(functionstr + "()", "JScript");

            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message.ToString());
            }     
        }

在这里,我向页面输出了一个msgActiveX变量,并调用了前面注册过的Js函数

而后,咱们还须要在页面加载的时候,调用插件的注册JS函数方法,以及此Js函数定义

<script type="text/javascript">
    Ext.onReady(
    function() {
        objCard.regJs(window, 'test');
    }
    );
    function test() {
        var str = msgActiveX.substring(5);
        var objJson = eval('(' + str + ')');
        alert(objJson.responseCode);
        //alert("回调函数执行成功");
    }
</script>

 

 至此,恭喜你已成功掌握了制做ActiveX浏览器插件的技能~

相关文章
相关标签/搜索