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瀏覽器插件的技能~

相關文章
相關標籤/搜索