通过Bytes加载程序集会丢失位置
本文关键字:位置 程序集 Bytes 加载 通过 | 更新日期: 2023-09-27 18:14:14
我想通过下面的
加载程序集 var loadedAssembly = Assembly.Load(File.ContentsAsBytes);
文件。ContentAsBytes返回dll作为byte[]
,通过以下
System.IO.File.ReadAllBytes("dll location");
问题是加载的程序集(loadedAssembly
)丢失了它的物理位置
- loadedAssembly。CodeBase -被设置为正在加载它的程序集(这是不正确的)
- loadedAssembly。位置-为空
是否有一种方法可以从byte[]
加载并获得与Assembly.LoadFile
类似的结果,因为我需要结果与AppDomain.CurrentDomain.AssemblyResolve
一起工作
字节数组byte[]
只是内存中的字节流。它与任何文件都没有关联。字节数组可以从文件中读取,从web服务器下载,或者由随机数生成器自发创建。没有额外的数据"与它一起"。
如果您想维护最初读取字节数组的文件位置,那么您必须在另一个变量中单独维护该数据。没有办法将额外的数据"附加"到byte[]
变量。
当你使用Assembly.Load
将字节数组作为程序集加载时,它无法知道字节数组来自哪里,因为额外的数据没有提供给Load
函数。
作为一种解决方案,是否有一种方法可以将字节数组保存到临时文件,使用Assembly.LoadFile
为您提供所需的数据,并将Location
链接回原始字节数组?
当然,您会认为 Location应该在某个地方有一个set方法,您可以访问或以其他方式调整它。它不是。发生的事情(我将mscorlib.dll放入IL DASM)是,当您从文件加载时,有一个本机句柄,它与类RuntimeAssembly中的程序集相关联。当你调用Location getter时,它会抓取这个句柄并从本机句柄中给你位置,但前提是有一个。没有句柄,没有位置
这是IL:
.method public hidebysig specialname virtual
instance string get_Location() cil managed
{
.custom instance void System.Security.SecuritySafeCriticalAttribute::.ctor() = ( 01 00 00 00 )
// Code size 37 (0x25)
.maxstack 3
.locals init (string V_0)
IL_0000: ldnull
IL_0001: stloc.0
IL_0002: ldarg.0
IL_0003: call instance class System.Reflection.RuntimeAssembly System.Reflection.RuntimeAssembly::GetNativeHandle()
IL_0008: ldloca.s V_0
IL_000a: call valuetype System.Runtime.CompilerServices.StringHandleOnStack System.Runtime.CompilerServices.JitHelpers::GetStringHandleOnStack(string&)
IL_000f: call void System.Reflection.RuntimeAssembly::GetLocation(class System.Reflection.RuntimeAssembly,
valuetype System.Runtime.CompilerServices.StringHandleOnStack)
IL_0014: ldloc.0
IL_0015: brfalse.s IL_0023
IL_0017: ldc.i4.8
IL_0018: ldloc.0
IL_0019: newobj instance void System.Security.Permissions.FileIOPermission::.ctor(valuetype System.Security.Permissions.FileIOPermissionAccess,
string)
IL_001e: call instance void System.Security.CodeAccessPermission::Demand()
IL_0023: ldloc.0
IL_0024: ret
} // end of method RuntimeAssembly::get_Location
一旦您将byte[]
传递给Assembly.Load
方法,该字节数组绝对没有任何信息甚至提示Load
方法它来自哪里-它只是一堆字节。如果您将该文件复制到另一个位置,则同样适用:
File.Copy(dllLocation, anotherLocation);
var asm = Assembly.LoadFile(anotherLocation);
程序集的位置将指向anotherLocation
,即使程序集最初是在dllLocation
上。类似地,当您加载程序集字节(本质上是将程序集从磁盘复制到内存)时,这些字节的"位置"现在是内存。