将运行时编译的程序集加载到不同的AppDomain失败

本文关键字:AppDomain 失败 加载 运行时 编译 程序集 | 更新日期: 2023-09-27 18:24:30

我试图将运行时编译的DLL加载到不同的AppDomain中。当对system.dll执行相同操作时,此操作不起作用。这是我的测试代码:

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

我收到以下"FusionLog"的FileNotFoundException

=== 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);  

将运行时编译的程序集加载到不同的AppDomain失败

程序集名称不包含程序集的完整路径-CLR无法找到"temp"程序集。如果要将特定程序集文件加载到AppDomain中,则必须使用byte[]重载。