1. 程式人生 > >使用C#開發ActiveX控制元件全攻略

使用C#開發ActiveX控制元件全攻略

前言:

這段時間因為工作的需要,研究了一下ActiveX控制元件。總結如下:

先說說ActiveX的基本概念。

根據微軟權威的軟體開發指南MSDN(Microsoft Developer Network)的定義,ActiveX外掛以前也叫做OLE控制元件或OCX控制元件,它是一些軟體元件或物件,可以將其插入到WEB網頁或其它應用程式中。

    ActiveX是Microsoft對於一系列策略性面向物件程式技術和工具的稱呼,其中主要的技術是元件物件模型(COM)。在有目錄和其它支援的網路中,COM變成了分散式COM(DCOM)。在建立包括ActiveX程式時,主要的工作就是元件,一個可以自足的在ActiveX網路(現在的網路主要包括Windows和Mac)中任意執行的程式。這個元件就是ActiveX近控制元件。ActiveX是Microsoft為抗衡Sun Microsystems的JAVA技術而提出的,此控制元件的功能和JAVA applet功能類似。

目前支援ActiveX的主要是IE瀏覽器。

以前ActiveX開發普遍使用VC++或VB,隨著C#和.net的釋出,用C#開發ActiveX控制元件變得更方便、更簡單。但需要注意的是用C#開發 的ActiveX控制元件需要客戶機裝有.net framework,有點鬱悶。可是相對.net強大的功能良好的易用性,這點犧牲還是值得的,況且現在好多計算機已經安裝有.net framework了。

其實.net下的winform控制元件也是可以直接嵌入到web網頁裡的,但是由於.net安全性的限制,無法在客戶端實現複雜的操作,比如磁碟空間操作和登錄檔操作。因為ActiveX控制元件是以本地使用者的身份執行,可以突破.net安全性的限制,所以開發ActiveX控制元件還是很必要的。

    C#寫ActiveX控制元件的原理很簡單,就是使用了.net平臺和COM的互操作性。修改專案屬性的目的就是將.net控制元件註冊為com。這樣,你就可以把這個控制元件完全當作ActiveX控制元件來對待了。比如,可以使用JS和VBS來呼叫,也可以使用C++來呼叫。

下面一步步來實現C#寫ActiveX控制元件。

第一部分:用vs2008製作一個winForm控制元件

用vs2008建立一個新的“windows窗體控制元件庫”命名為“WindowsFormsControlLibrary1”如下圖

clip_image001

點選確定後,將UserControl1.cs更名為demo.cs。向介面裡新增一個Labal、一個TextBox和一個Button,相應的修改控制元件屬性。如下圖:

clip_image002

為button1新增Click事件,程式碼如下:

private void button1_Click(object sender, EventArgs e)

        {

            label1.Text = textBox1.Text;

        }

在AssemblyInfo.cs中引用System.Security名稱空間,並新增一句:

clip_image003

[assembly : AllowPartiallyTrustedCallers()]

好,現在編譯整個工程,生成\bin\Debug\WindowsFormsControlLibrary1.dll,我們的winform控制元件就做好了。

下面在解決方案裡新增一個web應用程式的工程,名為WebApplication1,用來測試我們的控制元件。

將WindowsFormsControlLibrary1.dll拷貝到WebApplication1所在的目錄下。然後在Default.aspx 裡面加入“<object id="helloworld" classid='http://localhost:59639/WindowsFormsControlLibrary1.dll#WindowsFormsControlLibrary1.demo' width="184" height="96" >

    </object>

    ok,編譯執行後你將看到如下介面:

clip_image004

第二部分:把這個winForm控制元件轉換為ActiveX控制元件

到目前為止,我們所實現的只是winform控制元件,還不是真正的ActiveX控制元件。

滑鼠右鍵,開啟WindowsFormsControlLibrary1的工程屬性,在“應用程式”裡點選“程式集資訊...”顯示如下介面:

clip_image005

選中“使程式集COM可見”,然後確定。

進入“生成”頁面,如下圖:

clip_image006

選中“為COM互操作註冊”。

重新編譯工程,這時WindowsFormsControlLibrary1.dll就變成了一個ActiveX控制元件。

我們使用 Microsoft Windows SDK v6.0A—〉Tools—〉OLE/COM物件檢視器檢視,如圖:

clip_image007

    WindowsFormsControlLibrary1.demo已經被正確識別為COM元件。現在,我們已經可以像使用其它ActiveX控制元件一樣在 網頁中顯示了。在WindowsFormsControlLibrary1.demo點選滑鼠右鍵,選擇Copy HTML <object> Tag to Clipboard,可以將程式碼拷入剪貼簿。

我們在 Default.aspx  中貼上剪貼簿的內容,如下:

     <object id="helloworld" classid="clsid:A82F92E1-BA7F-3B32-B389-584E8AB4441F" width="184"> 

        </object>

編譯執行整個工程,我們會在網頁中看到之前的內容。好,現在我們的控制元件已經是貨真價實的ActiveX控制元件了。

第三部分:實現ActiveX控制元件與網頁的互動

我們在Demo中加入s1屬性:

        private string _s1;

        public string s1

        {

            get

            {

                return _s1;

            }

            set

            {

                _s1 = value;

            }

        }

我們在Demo中加入ShowMessage方法:

    public void showMessage()

        {

            MessageBox.Show(_s1);

        }

修改Default.aspx  中的內容:

        <object id="helloworld" classid="clsid:A82F92E1-BA7F-3B32-B389-584E8AB4441F"

            width="184">

            <param  name="s1" value="用param傳遞控制元件屬性"/>  

        </object>

        <input type='button' onclick='helloworld.ShowMessage()' value='用param傳遞控制元件屬性'/>

        <input type='button' onclick='helloworld.s1="用js和控制元件互動"; helloworld.ShowMessage()' value='用js和控制元件互動'/>

好,編譯執行整個工程,顯示如下:

clip_image008

點選單擊“用js和控制元件互動”按鈕,應該可以實現互動了。

但是結果卻很遺憾,我們發現IE跳出了對話方塊,如圖所示

clip_image009

這時我們通過修改IE安全屬性“對沒有標記為安全的ActiveX控制元件進行初始化和執行”可以繞過這個問題,但是要真正解決需要實現IObjectSafety介面,把ActiveX控制元件標記為安全的ActiveX控制元件。

首先在工程裡新增一個介面,命名為IObjectSafety.cs,程式碼如下:

using System;

using System.Runtime.InteropServices;

namespace WindowsFormsControlLibrary1

{

    [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); 

    }

}

注意新增名稱空間“using System.Runtime.InteropServices”,Guid一定不能搞錯。

然後在demo類裡新增繼承,如下:

public partial class demo : UserControl, WindowsFormsControlLibrary1.IObjectSafety

{...}

最後在demo類裡實現兩個特定方法:

public void GetInterfacceSafyOptions(Int32 riid, out Int32 pdwSupportedOptions, out Int32 pdwEnabledOptions)

{

// TODO: 新增 WebCamControl.GetInterfacceSafyOptions 實現 

pdwSupportedOptions = 1;

pdwEnabledOptions = 2;

}

public void SetInterfaceSafetyOptions(Int32 riid, Int32 dwOptionsSetMask, Int32 dwEnabledOptions)

{

// TODO: 新增 WebCamControl.SetInterfaceSafetyOptions 實現             

}

    重新編譯,然後將IE裡面的設定改回來。現在,我們發現,和JS的互動已經沒有問題了。

在前面我們已經完成了ActiveX控制元件的開發,接下來的就是釋出它了。

第四部分:製作安裝包

在解決方案中新增一個“安裝”專案,命名為SetupActiveX。

在專案的“應用程式資料夾”裡新增“主輸出專案”WindowsFormsControlLibrary1

將主輸出專案”WindowsFormsControlLibrary1的Register屬性改為vsdrpCOM.如圖:

clip_image010

現在我們生成安裝程式,並把相應得程式拷貝到正確的目錄中(本例中為預設網站目錄下的跟資料夾中)。

現在我們又要重新改動Default.aspx  檔案了。修改後的結果如下: 

    <div>

        <object id="helloworld" classid="clsid:A82F92E1-BA7F-3B32-B389-584E8AB4441F"

            width="184"

            codebase="Setup.exe">

            <param  name="s1" value="用param傳遞控制元件屬性"/>  

        </object>

        <input type='button' onclick='helloworld.ShowMessage()' value='用param傳遞控制元件屬性'/>

        <input type='button' onclick='helloworld.s1="用js和控制元件互動"; helloworld.ShowMessage()' value='用js和控制元件互動'/>

    </div>

注意,我們在object塊中加入了codebase屬性,這就是制定的下載控制元件的位置,可以使用相對路徑。

但是,我們現在還不能正確請求這個頁面,因為我們還沒有對我們的控制元件進行簽名。為了繞過這個問題,我們可以修改IE的安全屬性"對沒有標記為安全的ActiveX控制元件進行初始化和指令碼執行"和"下載未簽名的ActiveX控制元件"。

第五部分:給安裝包簽名

對於 Internet 應用程式的開發人員和使用者而言,程式碼安全是一個主要問題。有下列風險:惡意的程式碼、被篡改的程式碼和來自未知站點或作者的程式碼。

     Internet 開發時有兩種保證安全的基本方法。第一種方法稱為“沙箱”。在此方法中,應用程式只能訪問一組特定的API,並且被從潛在危險的 API(如檔案 I/O,程式可能在此毀壞使用者計算機中的資料)中排除。第二種方法使用數字簽名來實現。此方法對 Internet 稱為“收縮包裝”。使用私匙/公匙技術驗證和簽名程式碼。在程式碼執行之前,驗證其數字簽名,確保該程式碼的來源是已知的並且經過驗證,並且自簽名後該程式碼未被 更改過。

在第一種情形中,信任應用程式不會有任何損害,並且信任該應用程式的來源。在第二種情形中,使用數字簽名來驗證真偽。數字簽名是用於識別和提供關於程式碼發行者的詳細資料的工業標準。其技術基於標準,包括 RSA 和 X.509。瀏覽器一般允許使用者選擇是否希望下載並執行來源未知的程式碼。

給檔案簽名首先要獲得軟體發行證書。為此,必須向證書頒發機構提出請求(比如微軟或其他認證代理機構)。在申請期間,必須生成一個密匙對並向證書頒發機構提供標識資訊(如名字、地址和公匙)。還必須作出在法律上具有約束力的保證,即保證您不能也不會分發您知道或本應知道含有病毒或將以其他方式惡意損害使用者的計算機或程式碼的軟體。當然,這種認證是收費的,一般在2——8KRMB不等。

這裡,我們使用Microsoft.Net帶的MAKECERT和CERT2SPC實用工具生成測試的軟體發行證書。然後用這個測試證書通過 SignTool工具為我們的發行包簽名,當然,這對軟體發行是無效的,也就是說在Internet環境下還是需要修改IE安全設定才可以下載安裝。但是在區域網環境下可以實現直接下載安裝,僅可用於測試程式碼簽名。

     MAKECERT.exe、CERT2SPC.exe和SignTool.exe三個工具在C:\Program Files\Microsoft SDKs\Windows\v6.0A\bin 目錄下。你可以通過vs2008的“Visual Studio 2008 Command Prompt” 進入命令列狀態,這時系統會自動載入對應的Path引數,你在任何一個目錄下都可以直接執行著三個小工具了。

    1、用MAKECERT.exe建立用於數字簽名的公鑰和私鑰對

在命令列下輸入“makecert -ss lwchome -n "CN=lwchome CRD公司" -sv d:\test\lwchomecert.pvk -r d:\test\wchomecert.cer”

其中ss-主題的證書儲存名稱, n-證書頒發物件,此名稱必須符合 X.500 標準。最簡單的方法是在雙引號中指定此名稱,並加上字首 CN=;例如,"CN=myName"。注意這裡的CN必須大寫。-r-證書儲存位置,-sv 匯出私鑰檔案(為了簽名使用)。注意:這個時候會讓輸入三次密碼,三次要完全一致。

2、用Cert2Spc.exe生成spc發行者證書:cert2spc d:\test\lwchomecert.cer d:\test\lwchomecert.spc

    3、用SignTool.exe對安裝包數字簽名

       在命令列下輸入“signtool signwizard”,會彈出簽名工具介面如下:

clip_image011

點選下一步,輸入安裝包的位置:

clip_image012

點選下一步,選擇“自定義”

clip_image013

點選下一步,從檔案選擇:

clip_image014

選擇剛剛製作的證書d:\test\lwchomecert.spc,點選下一步:

clip_image015

選擇磁碟上的私金鑰檔案,選中剛剛生成的私金鑰d:\test\lwchomecert.pvk ,然後點選下一步,輸入剛剛的密碼顯示如下介面:

clip_image016

選擇md5,點選下一步:

clip_image017

此頁無需修改,直接點選下一步:

clip_image018

輸入描述和web位置,點選下一步:

clip_image019

clip_image020

完成輸入剛剛的密碼即可。

這時,滑鼠右擊安裝包檔案“setup.exe”,可以檢視數字簽名信息:

clip_image021

如果是正式發行,請從微軟或代理機構申請正式證書和金鑰,然後用signtool工具加密你的發行包即可。

第六部分:部署

將簽名的setup.exe拷貝到網站目錄下,替換之前沒有簽名的安裝包。用iis釋出網站,注意“執行許可權選擇純指令碼”