dbones
dbones

Reputation: 4504

Loading an assembly by Bytes loses the location

I want to load the assembly via the following

var loadedAssembly = Assembly.Load(File.ContentsAsBytes);

the File.ContentAsBytes returns the dll as a byte[], via the following

System.IO.File.ReadAllBytes("dll location");

The issue is the loaded assembly (loadedAssembly) loses its phyisical location

Is there a way to load from a byte[] and getting a similar result to Assembly.LoadFile as I need the the result to work with the AppDomain.CurrentDomain.AssemblyResolve

Upvotes: 14

Views: 3769

Answers (3)

plinth
plinth

Reputation: 49179

Sure, you'd think that Location would have a set method somewhere that you could access or some other way to tweak it. It doesn't. What happens (I dropped mscorlib.dll into IL DASM) is that when you load from file, there is a native handle that it associated with the assembly in the class RuntimeAssembly. When you call the Location getter, it grabs this handle and gives you the location from the native handle, but only if there was one. No handle, no location.

Here's the 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

Upvotes: 3

Matt Houser
Matt Houser

Reputation: 36053

A byte array byte[] is simply a stream of bytes in memory. It has no correlation to any file at all. That byte array could have been read from file, downloaded from a web server, or created spontaneously by a random number generator. There is no extra data that "goes with it".

If you want to maintain the file location where the byte array was originally read from, then you must maintain that data separately in another variable. There is no way to "attach" the extra data to the byte[] variable.

When you use Assembly.Load to load the byte array as an assembly, it has no way to know where that byte array came from, because that extra data is not provided to the Load function.

As a workaround, is there a way you can save your byte array to a temporary file, use Assembly.LoadFile to give you the data you need and link the Location back to your original byte array?

Upvotes: 5

carlosfigueira
carlosfigueira

Reputation: 87218

Once you pass the byte[] to the Assembly.Load method, that byte array has absolutely no information to even hint the Load method where it came from - it's only a bunch of bytes. The same would apply if you copied the file to a separate location:

File.Copy(dllLocation, anotherLocation);
var asm = Assembly.LoadFile(anotherLocation);

The assembly location will be pointing to anotherLocation, even though the assembly originally was on dllLocation. Similarly, when you load the assembly bytes (essentially copying the assembly from the disk to memory), the "location" of those bytes is now the memory.

Upvotes: 2

Related Questions