2011-02-04 2 views
3

Это просто странно. Вот код:AppDomain Creation: Разрешение ошибки «Не удалось загрузить файл или сборку»

AppDomain newDomain = AppDomain.CreateDomain("newDomain ", null, 
      new AppDomainSetup 
      { 
       ApplicationBase = @"D:\myDLLFolderFullPath\" 
      }); 

Assembly a = newDomain.Load("myAssembly"); 

Это вызывает ошибку «Не удалось загрузить файл или сборку».
Я проверил, что dll моей сборки находится в указанном пути к папке, и имя сборки правильное.

Когда я копирую файл myAssembly.dll в основную папку CurrentDomain, он работает!
Он ведет себя так, как если бы параметр ApplicationBase для нового AppDomain не имел никакого эффекта и продолжал указывать на AppBod текущего AppDomain.

Любые идеи?

+1

Ну, должно работать. Следите за зависимыми сборками. Используйте Fuslogvw.exe для диагностики неудачного связывания. –

+0

+1 для включения связывания журнала сварки и изучения результатов. –

ответ

1

Я не знаю, что вы хотите сделать точно ...

Но чтобы загрузить DLL в качестве AppDomain и создать экземпляр, вы можете сделать это следующим образом:

Создать AppDomain. Информация об установке и безопасности - это необязательные параметры.

var appDomain = AppDomain.CreateDomain("A friendly name to identify your application", null, null); 

Загрузите сборку:

var assemblyName = AssemblyName.GetAssemblyName(@"C:\PathToYourApp\ConsoleApplication1.exe")); 

Создание экземпляра внутри домена приложения:

var instance = (Program)appDomain.CreateInstanceAndUnwrap(assemblyName.Name, "ConsoleApplication1.Program"); 

Важно: класс, который вы хотите разворачивать и доступ за пределами вас приложения домена, было для маркировки [Serializable] Attrbute!

[Serializable] 
class Program{} 

Используйте событие appDomain.UnhandledException для обработки исключений вне AppDomain.

+4

Если этот класс помечен как [сериализуемый], он будет перенесен через границу домена, а сборка, в которой она определена, будет загружена в родительский домен. Если вы используете appdomains для выделения сборок, тогда 'Program' (ваш класс класса) должен расширять MarshalByRefObject. Когда вы вызываете CreateInstanceAndUnwrap, у вас будет прокси-сервер для типа, который существует во втором appdomain. – Will

1

Я не уверен, что .NET позволяет загружать сборки из путей, которые не относятся к основному исполняемому пути.

Так что, я думаю, что это не допускается:

D:\myExeFolderFullPath\main.exe 
D:\myDLLFolderFullPath\Mydll.dll 

... в то время как это должно работать:

D:\myExeFolderFullPath\main.exe 
D:\myExeFolderFullPath\myDLLFolderFullPath\Mydll.dll 

Update:

У меня была аналогичная проблема с пути при работе над проектом mygeneration. Единственный способ, которым я нашел его запустить, - это реорганизовать структуру папок, описанную в этом ответе.

+0

Вы уверены? Если да, то почему? Это странное ограничение ... –

+0

См. Также обновленный вопрос. Возможно, причина в том, что это связано с безопасностью. Высокоуровневое приложение не может ссылаться на другие компоненты вне gac или его бинарной папки. @Mika Jacobi: работает ли ваш код, если папки были реорганизованы так, как я предложил? – k3b

0

См для MSDN appDomain.load() метод: *

Этот метод должен быть использован только для загрузки сборки в текущем домене приложения.

  • Этот метод предоставляется в качестве удобства для совместимости абонентов, которые не могут вызвать статический метод Assembly.Load.Чтобы загрузить сборки в другие области приложений, используйте такой метод, как CreateInstanceAndUnwrap. Если версия запрошенной сборки уже загружена, этот метод возвращает загруженную сборку, даже если запрашивается другая версия.