2013-03-19 39 views
3

我發現,從自定義位置動態加載DLL,下面的代碼:如何動態加載包含其依賴項的自定義目錄中的程序集?

private void Form1_Load(object sender, EventArgs e) 
{ 
    AppDomain currentDomain = AppDomain.CurrentDomain; 
    currentDomain.AssemblyResolve += new ResolveEventHandler(MyResolveEventHandler); 
} 

private Assembly MyResolveEventHandler(object sender, ResolveEventArgs args) 
{ 
    string folderPath = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location); 
    string assemblyPath = Path.Combine(folderPath, "libs", new AssemblyName(args.Name).Name + ".dll"); 
    if (File.Exists(assemblyPath) == false) return null; 
    Assembly assembly = Assembly.LoadFrom(assemblyPath); 
    return assembly; 
} 

private void button1_Click(object sender, EventArgs e) 
{ 
    var zip = ZipFile.Read("test.zip"); 

    foreach (ZipEntry file in zip) 
    { 
     file.Extract(".", ExtractExistingFileAction.OverwriteSilently); 
    } 
} 

在某些情況下,這種解決方案的工作,但與ZipDotNet DLL我越來越:

InnerException {"File or assembly name \"Ionic.Zip, Version=1.9.1.8, Culture=neutral, PublicKeyToken=edbe51ad942a3f5c\" or one of its dependencies, was not found. Operation is not supported. (Exception from HRESULT: 0x80131515)":"Ionic.Zip, Version=1.9.1.8, Culture=neutral, PublicKeyToken=edbe51ad942a3f5c"} System.Exception {System.IO.FileLoadException} 


自從它通過if (File.Exists(assemblyPath) == false) return null;我猜測它加載Ionic.Zip.dll的依賴問題?我怎樣才能解決它們呢?

+1

你看了這裏:http://blogs.msdn.com/b/brada/archive/2009/12/11/visual-studio-project-sample-loading-error-assembly-could-not -BE加載和 - 將待忽略-可以-未負載文件或組裝-或酮 - - 它依賴性操作此結果不支持的異常從 - HRESULT-0x80131515 .aspx? – Dennis 2013-03-19 08:39:19

+0

嘗試將它與原始示例進行比較:http://support.microsoft.com/kb/837908 – Vedran 2013-03-19 08:49:03

+0

不能真的相信它,但丹尼斯是正確的...出於某種原因Ionic.Zip.dll被鎖定並解鎖它解決了這個問題......謝謝你的提示:) – lorus 2013-03-19 15:51:30

回答

4

看着Iconic.Zip.dll here的源代碼,我看到項目中唯一的引用是System,System.Data,System.Security和System.Xml,所以我懷疑原因是您無法加載任何參考。

我認爲你的程序集解析方法有點太簡單。假定程序集名稱與文件名相同,但情況並非總是如此。因此,您可以爲目標文件夾中的每個dll獲取AssemblyName,並將名稱映射到文件。然後,當解析器請求一個名稱時,您可以使用已知的名稱查找並加載彙編文件。這是一個快速實施的想法。

private Dictionary<string, string> assemblyNameToFileMapping = new Dictionary<string, string>(); 

private void Form1_Load(object sender, EventArgs e) 
{ 
    GetAssemblyNames(); 
    AppDomain currentDomain = AppDomain.CurrentDomain; 
    currentDomain.AssemblyResolve += new ResolveEventHandler(MyResolveEventHandler); 
} 

private void GetAssemblyNames() 
{ 
    string folderPath = Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), "libs"); 
    foreach(string file in Directory.EnumerateFiles(folderPath, "*.dll")) 
    { 
    try 
    { 
     AssemblyName name = AssemblyName.GetAssemblyName(file); 
     assemblyNameToFileMapping.Add(name.FullName, file); 
    } 
    catch { } // Just move on if we can't get the name. 
    } 
} 

private Assembly MyResolveEventHandler(object sender, ResolveEventArgs args) 
{ 
    string file; 
    if (assemblyNameToFileMapping.TryGetValue(args.Name, out file)) 
    { 
     return Assembly.LoadFrom(file); 
    } 
    return null; 
} 
相關問題