程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> C++ >> 關於C++ >> 實現應用程序中的並行組件共享(二)

實現應用程序中的並行組件共享(二)

編輯:關於C++

當將現有組件修改為並行時,正是將它的激活方式改為使用相對路徑和隔離全局狀態。重要的是給它一個新的 CLSID、ProgId,並且重命名該文件,然後將這個 CLSID、ProgId 以及新文件名用於後來的並行組件。這樣做可以避免在並行版本上再注冊該組件的非並行版本而引起的沖突。並行組件和他們以前的非並行版本不向後兼容。

狀態存儲

對於注冊表中存儲的狀態(設置),需要將狀態私有化為該應用程序運行的上下文。可以使用 GetModuleFileName() 函數設置一個虛擬根。應對 HKLM 和 HKCU 分支執行該操作。

必須在每個版本的基礎上完成注冊設置,以獲得注冊表的隔離。注冊表項是組件保存其狀態的通用方法。因為在機器中可能存在組件的不同版本,因此重要的是當重新編譯時,能盡可能容易地找到您的表項的版本。獲得一套優良的頭文件和有用的 API,會使得這件事情變得簡單。

用下列命名約定在表項中存儲注冊狀態:

HKCU\MyCompany\MyComponent\VersionXXXX\

例如,假定一個稱為 EnableSuperCoolFeature 的配置設置有真或假的值。在注冊表中存儲該信息的傳統方式為:

HKEY_CurrentUser\Software\MyCompany\MyComponent\

EnableSuperCoolFeature = TRUE

在並行共享情況下,應當用如下方式存儲它:

HKEY_CurrentUser\Software\MyCompany\MyComponent\Version01.01

EnableSuperCoolFeature = TRUE

另外,如果確定需要隔離每個應用程序,可以使用

HKCU\MyCompany\MyComponent\VersionXXYY\SomeApplication\\

其中“SomeApplication”是 GetModuleFileName 的返回值。這樣做使組件能夠隔離它的設置,該設置只針對當前正在運行的應用程序。

理想的情況下,應支持永久模型,以使應用程序擔負起保持用戶狀態的責任並且不更改注冊表。應用程序不必直接與組件的注冊表項接觸。作為代替,組件應提供一些 API,以保存或恢復與並行一致的設置。

對於全局狀態下的交互,存儲在除注冊表以外的其他位置的設置,應以並行方式存儲。這類存儲包含:

被保護的存儲 (pstore)

WinInet 高速緩存

Microsoft SQL Server™ 或 Microsoft Jet 數據庫

安裝並行組件

安裝之前

安裝並行組件之前,必須確定在您的操作系統中是否支持它們。下列代碼檢測並行共享是否可用。如果不可用,組件必須安裝在系統目錄中。

BOOL bPlatformSupportsSideBySide(void)

{

OSVERSIONINFOEX osviex ;

osviex.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX);

// 若平台不支持 OSVERSIONINFOEX 結構,就不支持並行

// 在內核中,我們已經使這些修改連在一起

//

if (!GetVersionEx((OSVERSIONINFO *)&osviex))

{

return FALSE ; // 無 DLL 重定向

}

// 然而對於 NT,則 NT4 SP4 支持 OSVERSIONINFOEX 支持,但它不支持 DLL 重定向。

// 若 DLL 重定向出現在將來的 NT4 SP 中,必須更新此代碼。

//

if ( (osviex.dwPlatformId == VER_PLATFORM_WIN32_NT) &&

(osviex.dwMajorVersion < 5) )

{

return FALSE ;

}

// 對於其他平台標識,假定具有並行支持

return TRUE ;

}

安裝與卸載

正確安裝和卸載組件很關鍵。理想情況下,除了將組件復制到應用程序目錄中或將其從應用程序目錄中刪除外,不應有其他的安裝和卸裝過程。但是,如果需要執行組件的 COM 注冊或其他初始設置,則必須以與並行一致的方式執行。

Windows 2000 包含 Windows Installer 版本 1.1,它將支持並行組件的安裝和卸載。(在 Windows 2000 發布之後,Windows Installer 還可以聯機使用。)當注冊並行 COM 組件時,需要確認“類”表中的屬性欄設置了 msidbClassAttributesRelativePath 位。這將用相對路徑名注冊組件,允許相同組件的多個副本共存。

切記,當組件在應用程序目錄中是私有的,一些其他應用程序可能在該機器中安裝了該組件的不同版本。當安裝或卸載該組件時,您不希望做有損於其他應用程序的事。因此使用您的組件的應用程序將靠您,通過自注冊入口點 DLLRegisterServer 或 DLLUnregisterServer(對於 COM 組件)或 DllInstall(對於 Win32 或 COM 組件)來正確安裝它。有關這些函數的詳細信息,請參閱“平台 SDK”中的 “Register Server”(英文)。

要在應用程序目錄中正確安裝組件,請像安裝常規組件一樣執行下列步驟:

注冊 GUID 時,確認它們有相對路徑名。

確認有對 GUID 的引用計數。

這有助於跟蹤安裝或卸裝該 GUID 的次數。

如果 GUID 存在,則增加您的引用計數。

如果它不存在,則需要添加 GUID,並放入一個引用計數。例如:

{00000109-0000-0010-8000-00AA006D2EA4}

\InprocServer32

Default = "mycomponent.dll"

ReferenceCount=1

注意  類型庫應包含在 DLL 中,並且不需要在系統注冊表中注冊。

要正確卸裝應用程序目錄中的組件, 請像安裝常規組件一樣執行下列步驟:

遞減引用計數。如果達到 0,則知道可以刪除 GUID,因為沒有其他用戶。如果大於 0,表示另一個應用程序安裝在系統中並依賴於注冊表的狀態。

DLL/COM 重定向

DLL/COM 重定向,要求在部署應用程序時該應用程序是可執行的,並且所有的隔離組件安裝在應用程序目錄中,而不是系統目錄中。另外,“.local”文件被部署在應用程序目錄中,以修改 Windows 綁定行為,使應用程序綁定到隔離組件,而不是全局共享版本。

於是,應用程序將使用能安全地並行運行同一組件的不同版本的組件,這些組件的不同版本安裝在其他位置、另一個應用程序目錄中或系統目錄中。如果系統中的另一個應用程序要求不同的版本,您的應用程序將不受影響,並且兩個應用程序將用它們各自的組件版本運行。

如果另一個應用程序在系統中安裝了新的組件版本,該應用程序的組件版本將保持不變,因為您已將它安裝到您的應用程序目錄中。在其他應用程序使用它的版本的同時,您的應用程序繼續使用隨該應用程序提供的組件版本。操作系統可以同時加載這兩個版本。

注意  必須用操作系統正確注冊隔離的 COM 組件,組件的每個版本才不會與該組件的其他可能存在的版本發生沖突。該注冊要求,雖然組件的實現可因版本而異,但諸如 CLSID、ProgID、類型庫和線程模型等注冊的 COM 元數據,不能因版本而異。

注意  Windows 2000 和 Windows 98 第二版本都支持 DLL/COM 重定向。在該版本以前的 Windows 操作系統不支持他們。

使用 DLL/COM 重定向

DLL/COM 重定向允許開發者或管理員有選擇地將現有組件與正在建立和開發的應用程序隔離開。本節討論如何激活 DLL/COM 重定向,以及如何選擇要隔離的組件 。

激活 DLL/COM 重定向

通過“.local”文件的形式在逐個應用程序的基礎上激活 DLL/COM 重定向。在與應用程序的 .exe 文件相同的目錄中,“.local”是一個空文件,它與應用程序的 .exe 文件名稱相同,並且在該名稱的結尾帶有“.local”。

例如,要為稱為“myapp.exe”的應用程序激活 DLL/COM 重定向,可在安裝 myapp.exe 的相同目錄中創建一個稱為“myapp.exe.local”的空文件。

一旦激活 DLL/COM 重定向,則每當應用程序裝入一個 DLL 或 OCX 時,Windows 將首先在安裝該應用程序的 .exe 文件的目錄中查找該 DLL 或 OCX。如果在安裝 應用程序的 .exe 文件的目錄中找到該 DLL 或 OCX 的一個版本,則不管在應用程序或注冊表中指定了什麼目錄路徑,應用程序都將使用它。如果在安裝應用程序的 .exe 文件的目錄中未發現該 DLL 或 OCX 的版本,則使用一般搜索路徑或服務器路徑。

選擇要隔離的組件

DLL/COM 重定向允許隔離現有組件,其中安裝在計算機中的應用程序需要相同組件的不同版本。不需要對該組件進行任何代碼更改,因為一旦激活,DLL/COM 重定向將更改 Windows 綁定行為。

但是到目前為止,並行執行組件的不同版本通常已不是設計所考慮的問題。當組件可以很容易地並行安裝(安裝在一個共享的位置並且與一個或多個應用程序隔離)時,它們可能不並行運行。假定任何時刻在計算機中只有一個組件版本,出現這種情況是因為一些組件使用全局狀態(如存儲在注冊表中的設置)。另外,當該組件定位它所需要的其他資源時,該組件可能會假設它所安裝的特定目錄。

由於這個原因,必須測試應用程序,該應用程序使用了安裝在自己身上和其他應用程序環境中的隔離組件,該組件是隔離的。Microsoft 的經驗表明在大多數方案中,共享的組件通常是可以並行運行的,但在某些情況下,可能需要關閉一個應用程序,然後才能運行下一個應用程序。

選擇要隔離的組件時應遵照下列指南:

不要嘗試隔離受“系統文件保護”(隨 Windows 2000 提供)所保護的文件,包括大部分 .sys、.dll、.exe 以及 .ocx 文件。

必須測試所有應用程序以確保並行的有效性,尤其在可能出現共享的區域中,因為沒有任何由當前操作系統強制的並行。

當心失去對組件進行快速修正的能力,因為它們現在在擅自定位的應用程序目錄中。作為管理員,您需要知道需要修正組件的所有位置。

方案 I:將 ActiveX Controls 專門用於應用程序

在該方案中,管理員無法開發新的應用程序,因為新的應用程序使用在 Visual Basic 中創作的 ActiveX 控件的版本。該版本不同於當前開發的應用程序所需要的版本。

這時,對於 ActiveX 控件的錯誤修正和其他修改引入了語義的差別。如,應用程序使用了一個有問題的控件版本,該控件版本沒有經過測試。管理員必須有能力運行不同版本的 ActiveX 控件,這些不同版本的 ActiveX 控件用於不同的應用程序,避免修正並重新測試可能受 ActiveX 控件更改影響的每個應用程序。

注意  在 Visual Basic 中,當前沒有可供開發人員編寫內在並行的 ActiveX 控件的便利途徑。這是因為用 Visual Basic 創作的 ActiveX 控件在注冊時將把 OCX 文件的全限定路徑寫入注冊表中。

管理員能夠強制新應用程序使用正確版本的 ActiveX 控件,並且通過將新應用程序的設置修改為下列值,以確認現有應用程序的配置沒有更改:

在應用程序的 .exe 文件所在的目錄中安裝 ActiveX 控件的新版本。

在應用程序的 .exe 文件所在的目錄中,安裝一個 .local 文件,以指定每當運行該應用程序時都應從應用程序的 .exe 文件所在目錄中裝入 ActiveX 控件。

方案 II:將 Win32 DLL 專門用於一個應用程序

在該方案中,管理員得知在開發了新的應用程序之後,一個現有的應用程序停止工作。管理員能夠診斷出問題是由於對共享組件進行修改引起的,這樣做會導致共享組件的新版本不支持對先前版本的向後兼容。

管理員能夠通過執行下列步驟修正應用程序:

將共享 DLL 的先前版本安裝到現有應用程序的 .exe 文件所在的目錄中。

在現有應用程序的 .exe 文件的所在目錄中創建一個 .local 文件。該 .local 文件指定當應用程序運行時,在應用程序的 .exe 文件所在目錄中找到的 DLL 應從這裡裝入。

安裝隔離的 COM Server 的注意事項

DLL/COM 重定向是通過在新的位置安裝 DLL 或 OCX 文件(專用於應用程序)來實現的,但是將不隔離與 COM Server 關聯的其他系統狀態,這對於隔離 COM Server 具有一些特定含義。

安裝隔離的 COM Server 時,應當小心,以確保如果在計算機中已安裝了組件的任何版本(例如通過其他應用程序),InprocServer 文件的位置不被隔離組件的新位置所覆蓋。對於隔離的 COM Server,在運行時忽略 InprocServer 文件位置。但是不使用 DLL/COM 重定向的現有應用程序要求 InprocServer 文件位置繼續指定先前安裝的 COM Server 的位置。這意味著:

安裝隔離的 COM Server 時,如果已在計算機中安裝任何版本的 COM Server,請不要在安裝時注冊隔離的 COM Server。

相反,如果隔離的 COM Server 的版本尚未安裝在計算機中,則必須注冊它。這種問題出現在當 COM Server 與應用程序隔離、被安裝在應用程序的 .exe 目錄下,然後又安裝了一個需要該組件的非隔離的應用程序。在這種情況下,卸載隔離的應用程序不可能將隔離的 COM 組件視為共享文件,因此卸載將中斷其他應用程序。這意味著:

當安裝隔離的 COM Server 時,如果在計算機中未安裝 COM Server 的任何版本,則將 DLL 或 OCX 文件復制到應用程序的 .exe 目錄和系統目錄(或一些其他共享位置)中,並且在系統目錄(或其他共享位置)中注冊副本。

對於現有組件,一些版本可能由一些應用程序共享,而另一些版本可能專門用於一些其他的應用程序,比較合理的經驗做法是:在安裝使用潛在共享組件的隔離版本的應用程序之後,確保安裝了該組件的共享版本和隔離版本,並且注冊了共享版本。這樣做允許卸載程序刪除隔離版本,而不必擔心會中斷其他應用程序

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved