C#制作ActiveX瀏覽器插件.net


開發環境:VS2008

第一步 創建項目

新建一個項目,選擇“Windows窗體控件庫”,創建一個用戶控件項目“ActiveXDemo”(注意,這里起名不能用中文,否則后面會出問題),里面有個用戶控件類UserControl1.cs

在類中寫上你自己需要的業務邏輯代碼,保存

第二步 設置項目屬性

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

設置項目屬性,右鍵項目——屬性

選擇“應用程序”,點開“程序集信息”

勾選“使程序集COM可見”,點“確定”

然后選擇“生成”,滾動拉倒底部,勾選“為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瀏覽器插件的技能~


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM