2015-11-26 5 views
2

Я пытаюсь загрузить DLL, которая была скомпилирована во время выполнения в другой AppDomain. Это не работает, делая то же самое для system.dll. Это мой тестовый код:Загрузка сборки, скомпилированной во время выполнения в разные AppDomain, не выполняется

string sourceCode = "using System;\r\n" + 
        "[Serializable]\r\n" + 
        "public class Program1{\r\n" + 
        " public static void Main1(){\r\n" + 
        "  int i = 100;\r\n" + 
        "  i++;" + 
        " }\r\n" + 
        "}"; 

CSharpCodeProvider provider = new CSharpCodeProvider(); 
CompilerParameters parameters = new CompilerParameters(); 
Assembly[] assembliesOfCurrentDomain = AppDomain.CurrentDomain.GetAssemblies();//this.CompilerResults.CompiledAssembly.GetReferencedAssemblies(); 

for (int runAssembliesInCurrDomain = 0; runAssembliesInCurrDomain < assembliesOfCurrentDomain.Length; runAssembliesInCurrDomain++) 
{ 
    try 
    { 
     parameters.ReferencedAssemblies.Add(assembliesOfCurrentDomain[runAssembliesInCurrDomain].Location); 
    } 
    catch 
    { 
    } 
} 

// True - memory generation, false - external file generation 
parameters.GenerateInMemory = false; 
parameters.OutputAssembly = "D:\\temp\\123.dll"; 
parameters.IncludeDebugInformation = true; 
parameters.ReferencedAssemblies.Add(Assembly.GetEntryAssembly().Location); 

// True - exe file generation, false - dll file generation 
parameters.GenerateExecutable = false; 
parameters.TreatWarningsAsErrors = true; 

CompilerResults results = provider.CompileAssemblyFromSource(parameters, sourceCode); 

Assembly own = Assembly.LoadFrom("D:\\temp\\123.dll"); 
Assembly system = Assembly.LoadWithPartialName("System"); 

AppDomainSetup appDomainSetup = new AppDomainSetup() 
{ 
    PrivateBinPath = @"D:\\temp" 
}; 

AppDomain domain = AppDomain.CreateDomain("hello", AppDomain.CurrentDomain.Evidence, appDomainSetup); 
domain.Load(system.GetName());    // works 
AppDomain.CurrentDomain.Load(own.GetName()); // works 
domain.Load(own.GetName());     // works not 

Я получаю FileNotFoundException со следующим «FusionLog»

=== Zustandsinformationen vor Bindung === 
LOG: Benutzer = LIGHTTRANS2\schoening 
LOG: DisplayName = 123, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null 
(Fully-specified) 
LOG: Appbase = file:///D:/schoening/Projekte_VL/Testprojekte/Compileing/WindowsFormsApplication1/bin/x64/Debug/ 
LOG: Ursprünglicher PrivatePath = NULL 
Aufruf von Assembly : (Unknown). 
=== 
LOG: Diese Bindung startet im default-Load-Kontext. 
LOG: Die Anwendungskonfigurationsdatei wird verwendet: D:\schoening\Projekte_VL\Testprojekte\Compileing\WindowsFormsApplication1\bin\x64\Debug\WindowsFormsApplication1.vshost.exe.config 
LOG: Die Computerkonfigurationsdatei von C:\Windows\Microsoft.NET\Framework64\v2.0.50727\config\machine.config wird verwendet. 
LOG: Die Richtlinie wird derzeit nicht auf den Verweis angewendet (private, benutzerdefinierte, teilweise oder pfadbasierte Assemblybindung) 
LOG: Download von neuem URL file:///D:/schoening/Projekte_VL/Testprojekte/Compileing/WindowsFormsApplication1/bin/x64/Debug/123.DLL. 
LOG: Download von neuem URL file:///D:/schoening/Projekte_VL/Testprojekte/Compileing/WindowsFormsApplication1/bin/x64/Debug/123/123.DLL. 
LOG: Download von neuem URL file:///D:/schoening/Projekte_VL/Testprojekte/Compileing/WindowsFormsApplication1/bin/x64/Debug/123.EXE. 
LOG: Download von neuem URL file:///D:/schoening/Projekte_VL/Testprojekte/Compileing/WindowsFormsApplication1/bin/x64/Debug/123/123.EXE. 

Извините, что немец, завтра я буду стараться размещать английскую версию. Любые идеи в чем разница между двумя сборками?

Сборка библиотеки DLL. У меня такая же проблема, если я прокомментирую все до строки Assembly own = Assembly.LoadFrom("D:\\temp\\123.dll") и использую DLL, скомпилированную в предыдущем прогоне.

Редактировать: Следующее предложение, я попробовал следующее, что тоже не работает.

Assembly own = Assembly.LoadFrom("D:\\temp\\123.dll"); 

AppDomainSetup appDomainSetup = new AppDomainSetup() { 
    PrivateBinPath = @"D:\\temp" 
}; 

//FileStream fs = own.GetFiles(true)[0]; // does not work either 
FileStream fs = new FileStream("D:\\temp\\123.dll", FileMode.Open, FileAccess.Read, FileShare.Read); 
byte[] rawAssembly = new byte[fs.Length]; 
fs.Read(rawAssembly, 0, (int)fs.Length); 

AppDomain domain = AppDomain.CreateDomain("hello", AppDomain.CurrentDomain.Evidence, appDomainSetup); 
domain.Load(rawAssembly); 
+0

Почему вы загружаете сборку в домен приложения? Что вы здесь делаете? Почему вы просто не загружаете сборку из * внутри * домена приложения, когда это действительно необходимо? – Luaan

+0

Мы хотим добиться того, чтобы пользователь мог управлять нашим приложением через собственный код. В этом коде он сможет использовать внешние библиотеки DLL. И будет возможно, что эти библиотеки DLL будут изменены во время работы нашего приложения, и изменения будут применены без перезапуска нашего приложения. – TSchoening

+0

Подождите, он не сработает на * first * 'Assembly.LoadFrom (" D: \\ temp \\ 123.dll ")' уже? Также обратите внимание, что вы неправильно настроили путь к отдельному ящику ('@" D: \\ temp "' дает 'D: \\ temp', а не' D: \ temp'). Какое исключение вы получаете с новым подходом? – Luaan

ответ

0

имя Сборка не содержит полный путь к сборке - СЬК не имеет какой-либо способ найти свою «временную» сборку. Если вы хотите загрузить конкретную сборку файл в AppDomain, вам придется использовать перегрузку byte[].

+0

Я пробовал ваше предложение и, к сожалению, оно не работает. См. Мой измененный вопрос. – TSchoening

Смежные вопросы