COM方法
COM是開發軟體組件的一種方法。組件實際上是一些小的二進制可執行程式,它們可以給應用程式,作業系統以及其他組件提供服務。開發自定義的COM組件就如同開發動態的,面向對象的API。多個COM對象可以連線起來形成應用程式或組件系統。並且組件可以在運行時刻,在不被重新連結或編譯應用程式的情況下被卸下或替換掉。Microsoft的許多技術,如ActiveX, DirectX以及OLE等都是基於COM而建立起來的。並且Microsoft的開發人員也大量使用COM組件來定製他們的應用程式及作業系統。
COM所含的概念並不止是在Microsoft Windows作業系統下才有效。COM並不是一個大的API,它實際上像結構化編程及面向對象編程方法那樣,也是一種編程方法。在任何一種作業系統中,開發人員均可以遵循“COM方法”。
一個應用程式通常是由單個的二進制檔案組成的。當編譯器生成應用程式之後,在對下一個版本重新編譯並發行新生成的版本之前,應用程式一般不會發生任何變化。作業系統,硬體及客戶需求的改變都必須等到整個應用程式被重新生成。
這種狀況已經發生變化。開發人員開始將單個的應用程式分隔成單獨多個獨立的部分,也即組件。這種做法的好處是可以隨著技術的不斷發展而用新的組件取代已有的組件。此時的應用程式可以隨新組件不斷取代舊的組件而漸趨完善。而且利用已有的組件,用戶還可以快速的建立全新的套用。
傳統的做法是將應用程式分割成檔案,模組或類,然後將它們編譯並連結成一個單模應用程式。它與組件建立應用程式的過程(稱為組件構架)有很大的不同。一個組件同一個微型應用程式類似,即都是已經編譯連結好並可以使用的二進制代碼,應用程式就是由多個這樣的組件打包而得到的。單模應用程式只有一個二進制代碼模組。自定義組件可以在運行時刻同其他的組件連線起來以構成某個應用程式。在需要對應用程式進行修改或改進時,只需要將構成此應用程式的組件中的某個用新的版本替換掉即可。
COM,即組件對象模型,是關於如何建立組件以及如何通過組件建立應用程式的一個規範,說明了如何可動態交替更新組件。
ActiveX與com組件
ActiveX是Microsoft對於一系列策略性面向對象程式技術和工具的稱呼,其中主要的技術是組件對象模型(COM)。在有目錄和其它支持的網路中,COM變成了分散式COM(DCOM)。在創建包括ActiveX程式時,主要的工作就是組件,一個可以自足的在ActiveX網路(網路主要包括Windows和Mac)中任意運行的程式。這個組件就是ActiveX控制項。ActiveX是Microsoft為抗衡Sun Microsystems的JAVA技術而提出的,此控制項的功能和java applet功能類似。
如果您使用的是Windows作業系統,您或許會注意到一些以OCX結尾的檔案。OCX代表“對象連結與嵌入控制項”(OLE),這個技術是Microsoft提出的程式技術,用於處理桌面檔案的混合使用。COM的概念已經取代OLE的一部分,Microsoft也使用ActiveX控制項代表組件對象。
組件的一大優點就是可以被大多數應用程式再使用(這些應用程式稱為組件容器)。一個COM組件(ActiveX控制項)可由不同語言的開發工具開發,包括C++和Visual Basic或PowerBuilder,甚至一些技術性語言如VBScript。
ActiveX控制項在Windows 95/NT和Macintosh中運行,Microsoft還準備支持UNIX的ActiveX控制項。
組件優點
組件架構的一個優點就是套用可以隨時間的流逝而發展進化。除此之外,使用組件還有一些可以使對已有套用的升級更加方便和靈活的優點,如套用的定製,組件庫以及分散式組件等。
使用組件的種種優點直接來源於可以將它們動態的插入或卸出套用。為了實現這種功能,所有的組件必須滿足兩個條件:第一,組件必須動態連結;第二,它們必須隱藏(或封裝)其內部實現細節。動態連結對於組件而言是一個至關重要的要求,而訊息隱藏則是動態連結的一個必要條件。
COM組件由以Win 32動態連線庫(DLL)或執行檔(EXE)形式發布的可執行代碼所組成。遵循COM規範編寫出來的組件將能夠滿足對組件架構的所有要求。COM組件可以給應用程式、作業系統以及其他組件提供服務;自定義的COM組件可以在運行時刻同其他組件連線起來構成某個應用程式;COM組件可以動態的插入或卸出套用。
惡意網站可以利用含有漏洞的COM組件接口,下載木馬,並且執行;
禁用com組件一般是指設定了Kill位,即IE瀏覽器不能使用這個組件,通俗講:通過設定Kill位,可以使InternetExplorer在使用默認設定時永不調用被禁用的com組件,從而禁止該控制項在Internet Explorer中運行。禁用含有漏洞的com組件後,IE就不能調用含有漏洞的COM組件;黑客利用有漏洞的COM組,寫成的網頁代碼就不能在IE中被執行,木馬等將不會被下載。
相關問題
禁用com組件可能導致的問題
線上播放功能的組件被禁用,會導致線上電影等線上視頻無法正常觀看。
線上防毒功能的組件被禁用,會導致線上防毒不能使用。
線上遊戲功能的組件被禁用,會導致線上遊戲無法玩。
com組件禁用後的具體情況,需要根據具體的com組件功能作判斷。
手動啟動COM組件操作方法
運行——regedit——找到被禁用的COM組件對應的clsid|註冊表鍵值——刪除具體值,或者整個鍵。
COM是Component Object Model (組件對象模型)的縮寫。 用戶需要什麼樣的軟體產品?這是一個復選題,但高效,健壯是肯定會被選中的。作為一名軟體開發人員如何做才能滿足用戶的需要呢?必須要保證升級套用時不破壞與以前版本的向後兼容性。必須做到擴展系統服務時不依賴特定的作業系統。面向對象的程式設計顯然是一次革命性的改變。採用面向對象的設計方法我們可以很容易的把要解決的問題事物抽象成各種類,並將內部動作封裝隱藏起來,只提供一些接口。但這並沒有完全解決我們的問題。昨天我在《程式設計師》雜誌上看到,現在是後OO時代,那OO以後是什麼呢?應該是面向組件吧。
手動啟動COM組件操作方法:
運行——regedit——找到被禁用的com組件對應的clsid|註冊表鍵值——刪除具體值,或者整個鍵。
剛剛讀完《COM技術內幕》一書,整理了一個FAQ,供大家在學習此書時參考。
這是第一部分,包含前3章的內容。
FAQ1:什麼是COM組件?〖第一章〗
Answer:
COM組件是以WIN32動態程式庫(DLL)或執行檔(EXE)形式發布的可執行代碼組成。
COM組件是遵循COM規範編寫的
COM組件是一些小的二進制執行檔
COM組件可以給應用程式、作業系統以及其他組件提供服務
自定義的COM組件可以在運行時刻同其他組件連線起來構成某個應用程式
COM組件可以動態的插入或卸出套用
COM組件必須是動態連結的
COM組件必須隱藏(封裝)其內部實現細節
COM組件必須將其實現的語言隱藏
COM組件必須以二進制的形式發布
COM組件必須可以在不妨礙已有用戶的情況下被升級
COM組件可以透明的在網路上被重新分配位置
COM組件按照一種標準的方式來宣布它們的存在
FAQ2:組件不是……?〖第一章〗
Answer:
COM組件不是一種計算機語言
COM組件不是DLL,只是利用DLL來給組件提供動態連結的能力
COM組件不是一個API函式集。
COM組件不是類
FAQ3:什麼是接口?〖第二章〗
Answer:
接口就是提供兩個不同對象間的一種連線。
電腦程式是通過一組函式而進行連線的,這組函式就是定義了程式中不同部分的接口。
DLL的接口就是它所輸出的那些函式。
C++類的接口就是該類的成員函式集。
COM中的接口是一組由組件實現的提供給客戶使用的函式。
在COM中接口是一個包含函式指針數組的記憶體結構,數組元素是一個由組件實現的函式地址。
FAQ4:接口的作用是什麼?〖第二章〗
Answer:
有了組件如何將它們連線起來構成某個應用程式,需要用接口。
在COM中接口就是一切,對客戶說組件就是接口集,客戶只能通過接口和組件打交道。
說明接口可以保護系統免受外界變化的影響。這是封裝的體現。
接口實現了使用戶使用同樣的方式來處理不同的組件。這是多態的體現。
FAQ5:什麼是IUnKnown? 〖第三章〗
Answer:
IUnKnown是一個接口。
所有COM接口都繼承IUnKnown。
IUnKnown的定義在WIN32 SDK中的UNKNWN頭檔案中。
///IUnKnown的定義
interface IUnKnown
{
virtual HRESULT __stdcall QueryInterface(const IID& iid,void **ppv)=0;
virtual ULONG __stdcall AddRef()=0;
virtual ULONG __stdcall Release()=0;
}
FAQ6:QueryInterface函式的作用是什麼?〖第三章〗
Answer:
QueryInterface是IUnKnown的成員函式,客戶可以通過此函式來查詢組件是否支持某個特定的接口。
QueryInterface函式返回一個指向組件支持的接口的指針。
如果QueryInterface函式沒有找到組件支持的接口則返回指針是NULL。
QueryInterface函式可以使用if…then…else語句、數組、散列表、樹來實現。
QueryInterface函式不能使用case語句,因為QueryInterface函式返回的是一個HRESULT結構而不是一個數。
QueryInterface也是一種無封處理組件版本的機制。這種機制使得組件的新舊不同的版本可以互操作。
FAQ7:QueryInterface函式的實現規則是什麼?〖第三章〗
Answer:
QueryInterface返回的IUnKnown指針總是相同。
若客戶獲得了某個接口,那么它總能獲得此接口。
客戶可以再次獲得已經擁有的接口。
客戶可以返回到起始接口。
若能夠在某個接口獲得某個特定接口,那么從任意接口都將可以獲得此接口。
FAQ8:接口的如何實現?
Answer:
COM接口在C++中是用純抽象基類實現。
一個COM組件可以支多個接口。
一個C++類可以使用多重繼承來實現一個支持多個接口的組件。
組件可以支持任意數目的接口。
接口應該具有不變性。在組件升級時應該不修改原來的接口,而是添加新的接口。
要精心設計實現接口,以使之能夠支持各種不同的實現。
FAQ9:QueryInterface函式的參數IID是什麼?〖第三章〗
Answer:
它是一個結構,接口標識符結構。
IID標識了客戶所需的接口。
每一個接口都有一個唯一的接口標識符。所以某個與IID相對應的接口絕對不會發生變化。
接口IID決定了COM組件的版本。
不同的接口具有不同的ID,包括不同版本的接口。
FAQ10:何時需要建立一個新的COM組件版本?〖第三章〗
Answer:
當為已有接口指定新的ID時應該是下面的條件至少有一個成立。
接口中函式的數目發生改變時。
接口中函式的順序發生改變。
接口中某個函式的參數發生改變
接口中某個函式的參數的順序發生改變
接口中某個函式的參數的類型發生改變
接口中函式的返回值發生改變
接口中函式的返回值類型發生改變
接口中函式的參數的含義發生改變
接口中函式的含義發生改變
簡單地說,COM是一種跨套用和語言共享二進制代碼的方法。與C++不同,它提倡原始碼重用。ATL便是一個很好的例證。源碼級重用雖然好,但只能用於C++。它還帶來了名字衝突的可能性,更不用說不斷拷貝重用代碼而導致工程膨脹和臃腫。
Windows使用DLLs在二進制級共享代碼。這也是Windows程式運行的關鍵——重用kernel32.dll, user32.dll等。但DLLs是針對C接口而寫的,它們只能被C或理解C調用規範的語言使用。由程式語言來負責實現共享代碼,而不是由DLLs本身。這樣的話DLLs的使用受到限制。
MFC引入了另外一種MFC擴展DLLs二進制共享機制。但它的使用仍受限制——只能在MFC程式中使用。
COM通過定義二進制標準解決了這些問題,即COM明確指出二進制模組(DLLs和EXEs)必須被編譯成與指定的結構匹配。這個標準也確切規定了在記憶體中如何組織COM對象。COM定義的二進制標準還必須獨立於任何程式語言(如C++中的命名修飾)。一旦滿足了這些條件,就可以輕鬆地從任何程式語言中存取這些模組。由編譯器負責所產生的二進制代碼與標準兼容。這樣使後來的人就能更容易地使用這些二進制代碼。
在記憶體中,COM對象的這種標準形式在C++虛函式中偶爾用到,所以這就是為什麼許多COM代碼使用C++的原因。但是記住,編寫模組所用的語言是無關的,因為結果二進制代碼為所有語言可用。
此外,COM不是Win32特有的。從理論上講,它可以被移植到Unix或其它作業系統。但是我好像還從來沒有在Windows以外的地方聽說過COM。
當然COM對象也需要用過一種特殊的邏輯來從記憶體中釋放對象。這種方法被稱為COM對象的引用計數。它是用來跟蹤活動引用的數目。當一個對象的引用計數為0,對象從記憶體中刪除。出現這種情況的主要問題是循環引用。如果存在兩個COM組件之間的循環引用,他們會不會從記憶體中釋放。