2013-03-19 5 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); 
    } 
} 

В некоторых случаях это решение работает, но с DLL ZipDotNet я получаю:

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

+0

Попробуйте сравнить его с исходным образцом: http://support.microsoft.com/kb/837908 – Vedran

+0

Не могу поверить в это, но Деннис прав ... по какой-то причине Ionic.Zip.dll был заблокирован и разблокировка исправила проблему ... спасибо за этот хороший намек :) – lorus

ответ

4

Рассматривая исходный код Iconic.Zip.dll here, я вижу, что единственными ссылками в проекте являются System, System.Data, System.Security и System.Xml, поэтому я сомневаюсь, что причина в том, что вы не можете загрузить какие-либо ссылки.

Я думаю, что ваш метод решения сборки слишком прост. Предполагается, что имя сборки совпадает с именем файла, что не всегда так. Итак, что вы можете сделать, это получить AssemblyName для каждой из DLL в целевой папке и сохранить сопоставление имен с файлами. Затем, когда распознаватель запрашивает имя, вы просматриваете его в своих известных именах и загружаете файл сборки. Вот краткая реализация идеи.

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; 
}