轉自:http://lwchome.spaces.live.com/blog/cns!791B533443007D37!234.entry
前言:
這段時間因為工作的需要,研究了一下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”如
點擊確定後,將UserControl1.cs更名為demo.cs。向介面裡添加一個Labal、一個TextBox和一個Button,相應的修改控制項屬性。如:
為button1添加Click事件,代碼如下:
private void button1_Click(object sender, EventArgs e)
{
label1.Text = textBox1.Text;
}
在AssemblyInfo.cs中引用System.Security命名空間,並添加一句:
[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,編譯運行後你將看到如下介面:
第二部分:把這個winForm控制項轉換為ActiveX控制項
到目前為止,我們所實現的只是winform控制項,還不是真正的ActiveX控制項。
滑鼠右鍵,開啟WindowsFormsControlLibrary1的工程屬性,在“應用程式”裡點擊“程式集資訊...”顯示如下介面:
選中“使程式集COM可見”,然後確定。
進入“產生”頁面,如:
選中“為COM互操作註冊”。
重新編譯工程,這時WindowsFormsControlLibrary1.dll就變成了一個ActiveX控制項。
我們使用 工具—〉OLE/COM對象查看器查看,
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和控制項互動'/>
好,編譯運行整個工程,顯示如下:
點擊單擊“用js和控制項互動”按鈕,應該可以實現互動了。
但是結果卻很遺憾,我們發現IE跳出了對話方塊,
這時我們通過修改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.:
現在我們產生安裝程式,並把相應得程式拷貝到正確的目錄中(本例中為預設網站目錄下的跟檔案夾中)。
現在我們又要重新改動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”,會彈出簽名工具介面如下:
點擊下一步,輸入安裝包的位置:
點擊下一步,選擇“自訂”
點擊下一步,從檔案選擇:
選擇剛剛製作的認證d:\test\lwchomecert.spc,點擊下一步:
選擇磁碟上的私密鑰檔案,選中剛剛產生的私密鑰d:\test\lwchomecert.pvk ,然後點擊下一步,輸入剛剛的密碼顯示如下介面:
選擇md5,點擊下一步:
此頁無需修改,直接點擊下一步:
輸入描述和web位置,點擊下一步:
新增時間戳記http://timestamp.verisign.com/scripts/timstamp.dll,點擊下一步:
完成輸入剛剛的密碼即可。
這時,滑鼠右擊安裝包檔案“setup.exe”,可以查看數位簽章資訊:
如果是正式發行,請從微軟或代理機構申請正式認證和密鑰,然後用signtool工具加密你的發行包即可。
第六部分:部署
將簽名的setup.exe拷貝到網站目錄下,替換之前沒有簽名的安裝包。用iis發布網站,注意“執行許可權選擇純指令碼”