您不指定您的環境是.NET還是直線Win32。
我假設它的Win32版本,因爲如果它的.NET這樣做的技術在全局程序集緩存等方面都更接近手。
在Win32而言,可以在以下兩種方式之一從共享位置加載的Dll:
使用調用LoadLibrary有明確完整路徑。這意味着您不能使用靜態鏈接 - 所有產品中使用的所有dll函數都必須通過GetProcAddress訪問。你不能從通過LoadLibrary加載的DLL導入C++類 - 它們必須靜態鏈接才能工作,所以這種方法可能或不可行。編寫可以僞裝成dll接口的shim頭文件並且在每次調用時都會根據需要及時執行dll加載和GetProcAddress,這並不難。
另一種選擇是將dll轉換成所謂的「並排組件」並將它們安裝到WinSxS存儲中。不要被這個大名字嚇倒。 「並排裝配」是指「一個Dll文件和帶有版本信息的清單文件」。 然後,每個應用程序都會將「強名稱」(包含版本信息)放入其應用程序清單中,以便使用它的每個dll,並且Win32 Dll加載程序將使用它從WinSxS存儲區中選擇正確的常用dll實例。其基本過程是在MSDN文章中描述Guidelines for Creating Side-by-side Assemblies
在Windows版本6.1及以上(在Windows Server 2008和諷刺的是名爲Windows 7)應用程序配置文件現在要做的支持Application Configuration Files
探測元件
這意味着您應該能夠爲包含要加載的dll程序集的文件夾提供路徑(相對於您的應用程序)。
好吧,我已經做了Windows 7的一些測試,這一點也適用:
假設你已經安裝在\ Program Files文件\ App1的應用app1.exe,依賴於一些常見的DLL「thedll。 DLL」
在應用程序文件夾(\ Program Files文件\應用1)創建一個文件App1.exe.config,並給它包含以下內容: -
<configuration>
<windows>
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<probing privatePath="..\AcmeCommon"/>
</assemblyBinding>
</windows>
</configuration>
現在,創建一個名爲\方案F文件夾iles \ AcmeCommon,並在其中一個文件夾acme.thedll,並將該dll.dll複製到\ Program Files \ AcmeCommon \ acme.thedll
也在AcmeCommon \ acme.thedll中創建一個名爲acme.thedll.manifest的文件 - this將成爲集清單描述組件稱爲「acme.thedll」
acme.thedll.manifest的內容將是: -
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
<assemblyIdentity name="acme.thedll" version="1.2.3.4" processorArchitecture="x86" type="win32"/>
<file name="thedll.dll"/>
</assembly>
現在我們有共同的DLL,在一個共同的位置,一個本地的sxs程序集。我們有應用程序,配置文件將在Windows 7和2008服務器(及以上)中告訴它在常用位置搜索程序集。但該應用程序仍然試圖鏈接到DLL作爲DLL,而不是通過組裝。
爲了讓應用程序加載程序集,我們需要嚮應用程序添加清單文件。如果您使用的是Visual Studio,那麼您的應用程序可能已經配置爲通過鏈接器和清單工具項目設置來創建和嵌入清單。在這種情況下,最簡單的方法,告訴應用程序有關的組件在項目中加入以下代碼到至少一個頁眉或C/CPP文件後重建它: -
#pragma comment(linker,"/manifestdependency:\"type='win32' name='acme.thedll' version='1.2.3.4' processorArchitecture='x86' language='*'\"")
如果您使用的是老式當應用程序加載Win32加載器將加載:構建環境中,體現在手工製作,您將需要與在應用1文件夾app1.exe.manifest合併以下XML:
<dependency>
<dependentassembly>
<assemblyidentity type="win32" name="acme.thedll" version="1.2.3.4" processorArchitecture="x86" language="*"/>
</dependentassembly>
</dependency>
這應該關閉圈應用程序清單(app1.exe.manifest或作爲RT_MANIFEST資源嵌入)並瞭解「acme.thedll」程序集。它還將加載應用程序配置文件(app1.exe.config)並瞭解搜索程序集的私有路徑。然後它會加載並添加「acme.thedll.manifest」到應用程序「激活上下文」。然後,當加載器嘗試加載「thedll.dll」時,它將搜索激活上下文db,在acme.thedll程序集中找到它,並從程序集位置加載它。
感謝您的回覆。不幸的是,我正在尋找不使用任何運行時動態鏈接方法(如Loadlibrary(..))的C/C++應用程序。無論如何要通過清單來指導「探索」概念如何運作? – Kartlee 2009-12-28 14:45:56
@Kartlee,對不起,我不瞭解C/C++;但我編輯了你的問題,以反映關鍵字 – 2009-12-28 14:50:12