2009-01-22 92 views
4

我前一段時間發佈了類似的問題。我需要在運行時加載程序集。.NET在運行時加載程序集再次

這很容易,如果我知道在運行時的DLL的絕對路徑。

但我不:(在assembly.Load()或LoadFromFile()如果文件不是在應用程序根失敗。

我的唯一的事情是DLL的名稱。該DLL可以設在系統32或甚至在GAC中。

是否有可能讓.net自動確定dll所在的位置,例如: 它應該首先查看根。如果它不存在系統文件夾,否則試試GAC。

EDITED

我正在使用插件架構。我不需要註冊該DLL。我有一個多用戶應用程序。我有一個包含應用程序信息的應用程序表。每個應用程序都有一個與它關聯的dll路徑,其中包含與該應用程序相關的某些算法。希望這可以幫助。

回答

1

該DLL將被自動找到它是在PATH系統變量(即system32)中引用的某個位置,或者如果該DLL已註冊。如果磁盤上的任何地方都可以使用,但無法找到該功能,但無法找到該功能。

編輯:可以註冊dll嗎?如果您提前不知道裝配,您如何獲得裝配名稱?您是否在創建某種類型的插件架構?我認爲如果你更多地解釋你的情況會有所幫助。

編輯2:如果是這種情況,爲什麼不提供一種方法讓用戶註冊他或她的插件?您可以從打開的文件對話框中獲取所需的所有信息。或者只是將它們轉儲到您指定的文件夾中。

+0

當我打電話的assembly.Load(「MyAssembly.dll程序」),我把該dll我system32,它不起作用。 – MegaByte 2009-01-22 06:53:55

+0

我認爲這適用於非託管DLL而非託管DLL。看到Lonzo的帖子,我認爲什麼是更好的迴應。 – Gishu 2009-01-22 07:20:32

2

您可以掛接到AppDomain.CurrentDomain.AssemblyResolve事件並根據需要手動加載應用程序的程序集。

+0

好吧,所以一旦我設置了所有其他路徑 - 我如何告訴CLR加載程序集?我仍然使用Load()方法嗎? – MegaByte 2009-01-22 08:10:52

1

是的有一種方法,它取決於你的DLL是弱(沒有公鑰標記)或強烈(與公鑰標記)命名。如果它的名字很弱,並且你在VS中添加了一個dll的程序集引用,那麼VS將首先查找應用程序的文件夾根目錄,如果它沒有找到它,它會查找你指定的子目錄中的值您的XML配置文件中的privatePath屬性。

如果它是一個強命名的dll,那麼CLR將在GAC中搜索,因此您需要在GAC中安裝dll。如果你安裝了一個XML配置文件,它的codeBase元素指向了dll的路徑,那麼CLR也可以在應用程序目錄中查找。

要在GAC中指定程序集,可以在編譯程序集時使用/ reference:[DLL name]開關。

1

我希望你已閱讀以下內容。我的建議...

  • How the runtime locates assemblies
  • 你可以給大會。 LoadWithPartialName旋轉..可能工作.. it says it will search the application folder and the GAC不像Assembly.Load。 (然而,它不太安全..因爲你可能以錯誤版本的DLL結束,因爲你沒有指定程序集名稱的全部4部分)
  • 另請嘗試AppDomainSetup.PrivateBinPath(AppDomain.AppendPrivatePath已被棄用, )將應用程序根目錄的子文件夾添加到要探測程序集的文件夾列表中。您也可以嘗試將其他位置的文件複製到添加到PrivateBinPath的[AppFolder] \ MySandboxForDLLsToLoad中。
0

使用此 Assembly.LoadWithPartialName(assemblyName);

2

當前應用程序查找程序集時,如果它找不到一個地方(bin文件夾,gac等),則開發人員需要手動告訴應用程序在哪裏查找。您可以通過攔截AssemblyResolve事件並使用事件參數來告知CLR組件的位置。

AppDomain.CurrentDomain.AssemblyResolve += CurrentDomain_AssemblyResolve; 
.................... 
Assembly CurrentDomain_AssemblyResolve(object sender, ResolveEventArgs args) 
{ 
    var strTempAssmbPath= 
      Path.GetFullPath("C:\\Windows\\System32\\" + args.Name.Substring(0, args.Name.IndexOf(",")) + ".dll"); 

    var strTempAssmbPath2= 
      Path.GetFullPath("C:\\Windows\\" + args.Name.Substring(0, args.Name.IndexOf(",")) + ".dll"); 


    if (File.Exists(strTempAssmbPath)) 
      return Assembly.LoadFrom(strTempAssmbPath); 

    if (File.Exists(strTempAssmbPath2)) 
      return Assembly.LoadFrom(strTempAssmbPath2); 
} 
1

你有三個選擇

  1. 在全局程序集緩存中安裝的組件(GAC)
  2. 使用應用程序配置(的.config)與標籤
  3. 使用AssemblyResolve事件文件

你可以找到詳細信息here

1

.NET用來查找程序集及其依賴項的解析算法非常簡單。

  1. .NET標識所需的版本。通常,關於相關程序集的信息出現在應用程序的程序集清單中。
  2. .NET僅搜索GAC(全局程序集緩存),只有在程序集名爲strong的情況下。
  3. 如果在GAC中找不到,並且如果.config文件存在,那麼.NET會搜索配置文件中指定的位置,否則.NET搜索包含可執行文件(.EXE)的目錄。
  4. 之後,如果程序集仍然沒有找到,應用程序因錯誤而終止。

Click here的視頻解釋.NET解析算法,並click here對後期綁定組件的視頻