C#编写ActiveX控件
利用雙休的時間研究了一下c#開發ActiveX控件。由于我用Vs2010開發,參考的文章不是Vs2010和Win7的環境下開發的,中間遇到許多問題,不過總算學到點東西。
?
我參考的文章如下(非Vs2010開發):?
??? 用C#編寫ActiveX控件(一)http://www.cnblogs.com/homer/archive/2005/01/04/86473.html
??? 用C#編寫ActiveX控件(二)http://www.cnblogs.com/homer/archive/2005/01/08/88780.html
??? 用C#編寫ActiveX控件(三)http://www.cnblogs.com/homer/archive/2005/01/26/97822.html
在我仔細看完上邊三篇文章之后,發現有用Vs2010開發的,如果想快速學習,可以參考下邊的文章。
??? .NET環境下創建Activex ?????http://www.cnblogs.com/liulixiang/archive/2011/05/23/2054371.html
??? 使用VS2010 C#開發ActiveX控件(上)?http://www.cnblogs.com/yungboy/archive/2011/01/10/1932433.html
??? 使用VS2010 C#開發ActiveX控件(下),完整代碼下載??http://www.cnblogs.com/yungboy/archive/2011/01/11/1932438.html
?
下邊對學習的內容進行總結,主要是對我參考的文章不足部分進行修改。
一. 建立ActiveX控件(暫時稱為ActiveX控件,其實是winform下的用戶控件)。
1.打開vs2010,新建空年方案。方案名稱自己取。
?? 然后,新建項目->Visual C#->Windows->類庫,名稱為HelloWorld。
2. 刪除自動創建的Class1.cs文件,然后在HelloWorld上右鍵->添加->新建項,在彈出的窗口中選擇“用戶控件”,名稱為Demo,此時會出現一個類似于winform設計界面,我們在上面從工具箱中拖動一個Label在上面,并設定Label的Text為"HelloWorld"。
此時編譯項目,可以生成HelloWorld.dll。 將此dll拷貝到IIS的虛擬根目錄下,然后在虛擬目錄的物理目錄下建立一個helloworld.htm的文件,html代碼如下:
<body?bgcolor='#223344'><object?id="helloworld"?classid=’http://localhost/HelloWorld.dll#HelloWorld.Demo’?Width="184"?Height="96"?VIEWASTEXT>?</object>
</body>
??? 注:我們可以在Object的classid中使用“http://localhost/類.dll#命名空間.類名”這樣的方式使用未注冊的控件(此時還不能稱為ActiveX)。
3、測試:在IE地址欄中輸入以下地址:http://localhost/helloworld.htm,出現下圖界面,控件已經成功在頁面上顯示了。OK,我們已經完成了第一步。
?
???? 但是問題到這里還沒有解決。不相信?你可以試試在另外一臺機器上測試,注意需要修改對應的html代碼和URL地址。你可以看到這個在原來顯示控件的地方是一個紅色的叉,或者還會彈出一個對話框,表示這個控件沒有任何權限。出現這個結果是微軟的默認設置造成的,必須在控件項項目中Properties下AssemblyInfo.cs中增加一個安全聲明,聲明這個控件必須使用賦予的權限,才可以顯示出界面。添加語句如下:
//設置控件的權限[assembly:?System.Security.AllowPartiallyTrustedCallers()]
???? 現在重新編譯,并且替換以前的dll,界面又可以顯示出來了。
?
??? 到現在為止,我們編寫的還不是真正的ActiveX控件。這個控件只是能夠實現自身的顯示,并且不能實現更多的功能,比如實現與腳本的交互或者操作客戶端的注冊表或者磁盤。這如果我們希望這個控件突破.Net Framework安全模型的限制,實現與腳本的交互或者操作客戶端的注冊表或者磁盤的話,必須要讓它成為真正的ActiveX控件。
?
二. 將用戶控件變成Com可見
??? 1.在HelloWorld(用戶控件)項目上點擊右鍵,選擇屬性,將打開項目屬性面板,選擇應用程序標簽頁,點擊“程序集信息”按鈕,在彈出的窗口中勾選“使程序集COM可見”(下圖為別人的圖片,僅供參考)
??? 2.切換到生成標簽頁,然后勾選“為Com互操作注冊”,在該頁面的最上面,有一個配置選項,切換到realse,并再次勾選“為Com互操作注冊”。這樣無論是在debug還是在release狀態下,都可以把用戶控件當做com接口使用。如下圖。(如果不使用realse模式,realse可以不設置。)
?
?????注意:在Win7中,溝選“為Com互操作注冊”后,如果不是Administrtor用戶,編譯項目會出錯。所以一定要記得在Administrator下編寫代碼。
?
3、修改用戶控件后臺代碼,代碼如下,?
using?System.Runtime.InteropServices;namespace?HelloWorld
{
????[Guid("F3F99F87-276D-4F7C-96F9-85F5261773CD")]
????public?partial?class?Demo:?UserControl
????{
????????public?Demo()
????????{
????????????InitializeComponent();
????????}??????
????}??
}
?
???? 注:創建Guid的方法如下:
??????? 在vs2010中,工具->創建GUID,在彈出的窗口中,在GUID格式中選擇第五個,點擊新建GUID,然后點擊復制,然后在點擊退出,此時返回到VS2010中,在相應位置粘貼即可。
?
?
?
???? 重新編譯,使用VS2010編譯后,此控件會自動被注冊在系統中。我們只需要在“OLE/COM對象查看器”中點Grouped by Component Category->.Net Category->點擊你編寫的類庫名.用戶控件類查看。如下圖。“OLE/COM對象查看器”位于開始菜單->Vs2010安裝目錄->Microsoft Windows SDK Tools中。
?
??可以看到,我們寫的HelloWorld.Demo已經被正確識別為COM組件。現在,我們已經可以像使用其它ActiveX控件一樣在網頁中顯示了。在HelloWorld.Demo點擊鼠標右鍵,如圖:?
?? 選擇Copy HTML <object> Tag to Clipboard,可以將代碼拷入剪貼板。?
???現在,我們改寫helloworld.htm,html代碼如下:
?
<body?bgcolor='#223344'>?<object?id="helloworld"?
???classid="clsid:9551B223-6188-4387-B293-C7D9D8173E3A"?Width="184"?Height="96">?
</object>?
</body>?
使用IE查看,我們的控件又可以在網頁中顯示了。不過,這個時候它已經不再是以前的.net WinForm控件了,而是貨真價實的ActiveX控件了。?
??? 不過,編寫ActiveX控件的任務還沒有完成。我們還沒有實現腳本互動或者讀寫I/O,也沒有實現ActiveX控件的自動分發。
?
三. 實現與Js交互
?????我們在Demo中加入ShowMessage方法:
public?void?ShowMessage(string?msg)?????????{?
????????????if(msg?!=?null)?
????????????{?
????????????????MessageBox.Show(msg);?
????????????}?
????????}?
??? 我們重新編譯。在重新訪問頁面之前,我們先來修改html代碼:
<body?bgcolor='#223344'>?<object?id="helloworld"?
???classid="clsid:9551B223-6188-4387-B293-C7D9D8173E3A"?Width="184"?Height="96"?
>?
</object>?
<br>?
<input?type='button'?onclick='helloworld.ShowMessage(“Hello?World!”)'?value='Click'>?
</body>?
??? 現在,重新訪問http://localhost/helloworld.htm,單擊Click按鈕,應該可以實現交互了。??
????但是結果卻很遺憾,我們發現IE跳出了對話框,(注,我在編寫此項目時,好像沒有跳出這個提示。)如圖所示:?
??? 單擊確定之后,我們發現JS報錯。根據提示,我們判斷可以通過修改IE的設置使控件運行。打開IE的 工具——〉Internet選項——〉安全——〉
本地Intranet——〉自定義級別——〉對沒有標記為安全的ActiveX控件進行初始化和運行,將其值設為啟用。我們刷新頁面,現在終于可以正確運行了。
?
??? 當然,我們不能指望我們的客戶和我們一樣修改這個值。畢竟,一是操作麻煩,二是給電腦帶來了很大的安全風險。所以需要自義IObjectSafety接口,并讓UserControl實現接口。
??? 首先我們自己用C#定義這個接口,此接口必須與下邊接口代碼相同,包括Guid值都要一樣。
using?System.Runtime.InteropServices;namespace?HelloWorld
{
????[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);
????}
????public?class?CLsObjectSafety
????{
????????public?const?System.Int32?INTERFACESAFE_FOR_UNTRUSTED_CALLER?=?0x00000001;
????????public?const?System.Int32?INTERFACESAFE_FOR_UNTRUSTED_DATA?=?0x00000002;
????}
}
???? 在UserControl后臺實現接口,代碼如下。
using?System.Runtime.InteropServices;namespace?HelloWorld
{
????[Guid("F3F99F87-276D-4F7C-96F9-85F5261773CD")]
????public?partial?class?Demo:?UserControl,IObjectSafety
????{
????????public?Demo()
????????{
????????????InitializeComponent();
????????}
????????public?void?ShowMessage(string?msg)
????????{
????????????if?(msg?!=?null)
????????????{
????????????????MessageBox.Show(msg);
????????????}
????????}
????????public?void?GetInterfacceSafyOptions(Int32?riid,?out?Int32?pdwSupportedOptions,?out?Int32?pdwEnabledOptions)
????????{
????????????//?TODO:??添加WebCamControl.GetInterfacceSafyOptions?實現
????????????pdwSupportedOptions?=?CLsObjectSafety.INTERFACESAFE_FOR_UNTRUSTED_CALLER;
????????????pdwEnabledOptions?=?CLsObjectSafety.INTERFACESAFE_FOR_UNTRUSTED_DATA;
????????}
????????public?void?SetInterfaceSafetyOptions(Int32?riid,?Int32?dwOptionsSetMask,?Int32?dwEnabledOptions)
????????{
????????????//?TODO:??添加WebCamControl.SetInterfaceSafetyOptions?實現
????????}
????}??
}
???? 重新編譯,然后將IE里面的設置改回來。現在,我們發現,和JS的交互已經沒有問題了。???
????? 這樣,一個最基本的ActiveX控件已經寫好了。你可以在這個控件的基礎上增加任何你需要的功能。到這里,編寫控件的任務已經完成了。
?
四.打包并發布ActiveX ActiveX控件開發完成后,我們要將ActiveX控件打包和發布,以便于用戶安裝。ActiveX控件可以使用VS 2010的安裝項目進行部署,使用VS 2010 創建Windows Form的安裝工程就可以將ActiveX的dll進行打包。在打包時注意將ActiveX控件項目作為主輸出項目,并設置其Register屬性為vsdrpCOM, 創建打包項目如下圖所示:?????? 創建一個Windows 安裝項目,并給項目添加項目輸出,如下圖所示: 在添加項目輸出時,我們將ActiveX項目添加進來,在項目中選擇ActiveX控件項目(CardReader.Controls),Primary Out(基本輸出),如下圖所示:添加完文件后,設置Primary Output From CardReader.Controls的Register屬性為vsdrpCOM。
?
設置完成后右擊安裝工程,修改安裝工程屬性,如下圖所示:
??????????在上圖中可以設置輸出的文件名,這個文件名就是打包后安裝文件.MSI的文件名。設置包文件、壓縮方式,CAB size,這三項均選擇默認值即可。
最后設置安裝URL,這里的安裝URL是用來發布或者使用ActiveX的URL地址的。(此處我沒弄明白這個地址到底有什么用?)
?? ? 注:打包成exe文件以后,我們可以進一步對安裝文件進行打包成.cab文件,安裝隱藏了msi?安裝界面,類似于cabarc?打包ocx?的效果
(點擊install?之后其他的都后臺做了),本文中暫不討論,感興趣的讀者可以使用CAB SDK?中的工具CABARC.EXE (下載地址?http://support.microsoft.com/kb/310618?)來進行。
?這樣打包文件就生成了,將生成后的安裝文件(exe和msi)拷貝到(本例中為默認網站目錄下的ActiveX文件夾中),現在我們又要重新改動helloworld.htm文件了。修改后的結果如下:?
<body?bgcolor='#223344'><object?id="helloworld"
???classid="clsid:9551B223-6188-4387-B293-C7D9D8173E3A"?Width="184"?Height="96"?codebase="Setup.exe">?
</object>
<br>
<input?type='button'?onclick='helloworld.ShowMessage("Hello?World!")'?value='Click'>
</body>
??
??? 注意,我們在object塊中加入了codebase屬性,這就是制定的下載控件的位置,可以使用相對路徑。當使用codebase進行安裝時,Ie仍然會攔截,不允許安裝。需要將當前網站添加到信任站點中。如果這樣的話,可以直接給個鏈接讓用戶自已下載安裝。對于這兩種方法需要待觀察。
?
??? 別忙,我們現在還不能正確請求這個頁面,因為我們還沒有對我們的控件進行簽名。
????簽名可以采用兩種方式,一種是在上面生成安裝程序的時候簽名,另一種是使用sn.exe簽名。推薦大家使用后者。
?
說明:本文摘自多個文章,主要是學習使用。
總結
以上是生活随笔為你收集整理的C#编写ActiveX控件的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 华为服务器型号H22H-05,华为h22
- 下一篇: 计算机教学楼起名,学校教学楼起名(文雅的