[.NET] 使用 .NET Framework 開發 ActiveX Control (1)–背景知識

本文會介紹 ActiveX Control 的背景知識,以及在 .NET 上開發 ActiveX Control 的基礎。

ActiveX的歷史與技術基礎

只要是有八年以上程式開發經驗的開發人員,多多少少都會聽過ActiveX控制項(Control)這個東西,這個是只存活在Internet Explorer上的可程式化元件(Programmable Component),它可以允許在瀏覽器上執行低階層次的系統呼叫與存取工作,在Web應用程式平台發展的初期,當時網景公司(Netscape)的Navigator瀏覽器正和Internet Explorer打得火熱的時候,微軟為了要能對抗在Navigator內的Plug-in技術,在Internet Explorer內也加入了允許開發人員在網頁內加入具有動態效果的使用者介面元件的技術,ActiveX技術就這樣誕生了,在第一輪的瀏覽器大戰由微軟勝出後,許多的ActiveX控制項也如雨後春筍般的冒出來,也因為ActiveX控制項是目前唯一可以在IE瀏覽器上繞過瀏覽器沙箱(Browser Sandbox)而直接與系統層次溝通的元件,所以現在仍廣為金融界所應用(開發網路ATM),國內除了金融界以外,政府單位也是大客戶(應用自然人憑證驗證機制)。

ActiveX技術是1996年出現的,它的核心是COM(Component Object Model),當時COM和OLE是兩個不同的技術,而微軟為了要讓OLE可以在Internet上使用,特別在COM以及OLE中加入一些特別的介面,讓應用程式可以透過一個簡單的介面來存取在元件內的所有功能,以往要開發一個COM元件,必須要實作IUnknown介面以及應用程式自己的介面,並將介面註冊到COM Registry Databases(HKEY_CLASS_ROOT)內,而用戶端程式使用COM Client Library先自元件取得IUnknown介面以及呼叫由元件所實作的QueryInterface()方法取得元件自己的介面後,才可以呼叫自己的介面,而且沒有可以間接呼叫的方式,這種模式不利於在Internet上使用,而且當時Visual Basic 4.0也提供了OCX的控制項(OLE Control)開發能力,微軟也想要讓VB可以開發COM元件,因此微軟在COM介面中加入了一個新的介面-IDispatch介面,並且由COM Client Library直接支援,大家最常用的Office應用程式的核心部份就是利用IDispatch來實作各類物件,除了可以在應用程式間使用OLE來分享資料外,還可以讓VB或其他程式語言透過COM介面來存取Office的物件模型,這樣的作法讓COM獲得了巨大的支持,除了VB可開發COM元件外,其他的程式語言也可以遵循IDispatch介面實作來支援COM元件的開發。這樣的技術後來整合了OLE的部份技術後,稱為COM Automation(COM自動化)。

NOTE
在ActiveX推出的時候,微軟為了要支援開發ActiveX Control,另外提供了一個小工具:ActiveX Control Pad,可用來測試開發完成的控制項。您可以到此懷舊一下ActiveX Control Pad:http://msdn.microsoft.com/en-us/library/ms975966.aspx

後來在Visual Basic 6.0推出(1998年)時,微軟的各式Internet應用程式開發成員皆已到位,像ASP/ADO這類的基礎元件,以及Visual Studio 6.0套裝開發工具等,讓微軟的Internet開發技術紅極一時,當時作為核心技術的ActiveX也被提升到市場行銷上,許多COM/OLE技術都被改為ActiveX技術,像ActiveX Document(原本是OLE Document)、ActiveX DLL(原本是COM DLL)、ActiveX EXE(原本是COM EXE)等。後來到了Microsoft .NET時代,ActiveX控制項的發展也開始走下坡,同一時期的Flash則是開始竄起,第二次瀏覽器大戰更讓IE的市佔率開始下降,相對的ActiveX控制項也開始式微-因為它只有IE這個舞台。不過它可以存取硬體,且可由簡單的程式語言開發的優點仍然受到開發人員歡迎,所以只要特殊的應用環境不消失,ActiveX控制項也不會消失(因為在IE上的Flash本身也是ActiveX控制項)。

.NET時代的ActiveX控制項

在微軟宣布全力支援Microsoft .NET平台的發展與Visual Basic經過本質上的變化(VBàVB.NET)後,ActiveX控制項的開發就停頓在C++(MFC/ATL)、VB 6.0以及Delphi等開發工具,且COM本身也已經趨於穩定,只有很少量的基礎變化,所以開發ActiveX控制項的方法也沒有再繼續進化,目前開發ActiveX控制項的作法其實和八年前沒什麼兩樣,欽定的開發工具仍然是C++以及VB 6.0,反觀.NET Framework本身因為龐大的.NET Framework Class Libraries的關係,無法像C++/VB 6.0一樣可以產生輕薄短小的封裝檔,且在當時COM Interoperability仍然不夠成熟的情況下,原則上微軟並不建議使用.NET Framework來開發ActiveX控制項的(但鼓勵在.NET應用程式內使用ActiveX控制項,以保有原本的技術投資),不過近幾年來CPU以及運算能力的強化,COM Interoperability的效能損耗逐漸降低,只要能夠避免將.NET Framework一起封裝的情況下,.NET Framework也可以用來開發ActiveX控制項。

要使用.NET Framework來開發ActiveX控制項,則必須要先了解.NET Framework如何將自己的資訊開放給COM,既然都要讓COM來存取了,那麼當然也要將自己的型別資訊開放給COM知道。其實要開放.NET Framework物件給COM這件事不難,只要在專案的內容中,在『建置』頁籤中,將『註冊COM Interop』核取起來,這樣Visual Studio會在建置時另外產生一個型別函式庫(Type Library),並且使用Regasm.exe將組件註冊到COM Registry Database中,讓COM用戶端應用程式可以看到這個COM元件。

clip_image002

接著,要設定COM用戶端程式可以看到這個組件的多少物件,若是只要看到自己設定的物件類別時,則在物件類別上設定ComVisibleAttribute特徵項(attribute),若是要讓COM用戶端看到組件內的所有公開類別時,就要設定讓此組件為COM Visible,方法是打開專案內的Assembly.cs程式,並將下列指令的false改為true:

[C#]
[assembly: ComVisible(true)]

然後要為類別設定COM Visible,以及設定一個自己使用的GUID值,這個值會在登錄介面時寫入COM Registry Database內,而COM用戶端程式就依據這個值和由編譯器自動產生的Programmable ID(ProgID)進行對應,以正確呼叫你的組件。

[Guid("C90E96C1-8534-4243-9530-960D9AF982CB")]
[ComVisible(true)]
public class MyDateControl

設定完後編譯專案,即可將組件開放給COM用戶端。

(To be continued...)