我有一个 asp.net 应用程序,它从用户脚本动态生成程序集。一切正常,但现在我想在沙盒应用程序域中以减少的权限运行程序集。当我在新的应用程序域中加载程序集时,我得到了异常
无法加载文件或程序集“genb3336c1d82074079911fb70bd8bd7e65.dll,Version=1.0.0.0,Culture=neutral,PublicKeyToken=null”或其依赖项之一。该系统找不到指定的文件。
为了查看发生了什么,我将生成的程序集保存到磁盘,并使用以下代码编写了一个简单的应用程序
string path = @"test.dll";
byte[] buffer = File.ReadAllBytes(path);
var assembly = AppDomain.CurrentDomain.Load(buffer); //This works
var appDomain = AppDomain.CreateDomain("Test");
assembly = appDomain.Load(buffer); //Exception
当我再次尝试在新域中加载程序集时,我得到了同样的异常。在 CurrentDomain 中加载它可以正常工作。
然后我创建了一个类库,其中只有一个类和我从中生成 dll 的源代码。源代码最少,一个方法只有 2 行代码。现在,当我在新的应用程序域中构建和加载这个 dll 时,它加载得很好。
所以我不知道生成的dll有什么问题。我使用以下代码生成程序集。
public class ScriptCompiler
{
public static (byte[], byte[], Assembly) Compile((string Source, string Path)[] sources, string[] references, params Type[] types)
{
var assemblyName = "gen" + Guid.NewGuid().ToString().Replace("-", "") + ".dll";
byte[] rawAssembly;
byte[] rawPdb;
#if DEBUG
var encoding = Encoding.UTF8;
var symbolsName = Path.ChangeExtension(assemblyName, "pdb");
var sourceTexts = sources
.Select(s => new { Buffer = encoding.GetBytes(s.Source), s.Source, s.Path })
.Select(b => new { SourceText = SourceText.From(b.Buffer, b.Buffer.Length, encoding, canBeEmbedded: true), b.Path });
var syntaxTrees = sourceTexts
.Select(s => new { Tree = CSharpSyntaxTree.ParseText(s.SourceText, new CSharpParseOptions(), s.Path), s.Path })
.Select(t => new { Node = t.Tree.GetRoot() as CSharpSyntaxNode, t.Path })
.Select(n => CSharpSyntaxTree.Create(n.Node, null, n.Path, encoding));
var options = new CSharpCompilationOptions(OutputKind.DynamicallyLinkedLibrary).WithOptimizationLevel(OptimizationLevel.Debug);
#else
var syntaxTrees =
from source in sources.Select(s => s.Source)
select CSharpSyntaxTree.ParseText(source);
var options = new CSharpCompilationOptions(OutputKind.DynamicallyLinkedLibrary).WithOptimizationLevel(OptimizationLevel.Release);
#endif
var typeRefs = new List<MetadataReference>();
foreach (var type in types)
{
typeRefs.Add(MetadataReference.CreateFromFile(type.Assembly.Location));
}
var compilation = CSharpCompilation.Create(assemblyName,
options: options,
syntaxTrees: syntaxTrees,
references: typeRefs.Union(references.Select(r => MetadataReference.CreateFromFile(r))));
EmitResult emitResult;
using (var peStream = new MemoryStream())
using (var pdbStream = new MemoryStream())
{
#if DEBUG
emitResult = compilation.Emit(
peStream: peStream,
pdbStream: pdbStream,
embeddedTexts: sourceTexts.Select(s => EmbeddedText.FromSource(s.Path, s.SourceText)),
options: new EmitOptions(debugInformationFormat: DebugInformationFormat.PortablePdb, pdbFilePath: symbolsName)
);
#else
emitResult = compilation.Emit(peStream: peStream);
#endif
if (emitResult.Success)
{
rawAssembly = peStream.GetBuffer();
rawPdb = pdbStream.GetBuffer();
var assembly = Assembly.Load(rawAssembly, rawPdb);
return (rawAssembly, rawPdb, assembly);
}
}
var message = string.Join("\r\n", emitResult.Diagnostics);
throw new ApplicationException(message);
}
}
有人知道吗?
编辑: 这是融合日志。我不知道如何解释它。
=== Pre-bind state information ===
LOG: DisplayName = genb3336c1d82074079911fb70bd8bd7e65.dll, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null
(Fully-specified)
LOG: Appbase = file:///C:/Users/Admin/source/repos/LoadAssembly/LoadAssembly/bin/Debug/
LOG: Initial PrivatePath = NULL
Calling assembly : (Unknown).
===
LOG: This bind starts in default load context.
LOG: Using application configuration file: C:\Users\Admin\source\repos\LoadAssembly\LoadAssembly\bin\Debug\LoadAssembly.exe.Config
LOG: Using host configuration file:
LOG: Using machine configuration file from C:\Windows\Microsoft.NET\Framework\v4.0.30319\config\machine.config.
LOG: Policy not being applied to reference at this time (private, custom, partial, or location-based assembly bind).
LOG: Attempting download of new URL file:///C:/Users/Admin/source/repos/LoadAssembly/LoadAssembly/bin/Debug/genb3336c1d82074079911fb70bd8bd7e65.dll.DLL.
LOG: Attempting download of new URL file:///C:/Users/Admin/source/repos/LoadAssembly/LoadAssembly/bin/Debug/genb3336c1d82074079911fb70bd8bd7e65.dll/genb3336c1d82074079911fb70bd8bd7e65.dll.DLL.
LOG: Attempting download of new URL file:///C:/Users/Admin/source/repos/LoadAssembly/LoadAssembly/bin/Debug/genb3336c1d82074079911fb70bd8bd7e65.dll.EXE.
LOG: Attempting download of new URL file:///C:/Users/Admin/source/repos/LoadAssembly/LoadAssembly/bin/Debug/genb3336c1d82074079911fb70bd8bd7e65.dll/genb3336c1d82074079911fb70bd8bd7e65.dll.EXE.