Net load assembly from dll byte array

System Requirements: Windows 8, Windows 7, Windows 8.1


I'm trying to dynamicaly load some C DLLs on a C application. I got all the DLL in a byte[] list and I want to load them without writing them to dll file. My application crashes when I want to use a dll application. It returns me a System. IO. File Not Found Exception because it does not find the dll file. I use Assembly. Load on each byte[] dll and it seems to work properly (no crash and the Assembly List count for the increase) and I load them in the good order ( I don't know it it is necessary). Assembly assembly = Assembly. Load(bin Dll Assembly Name[] referenced Assembly = assembly. Get Referenced Assemblies foreach ( Assembly Name referenced Assembly Name in referenced Assembly) if (!loaded Dll List. Contains(referenced Assembly Name. Name) TX. Add In Store. Load(bin Dll, dll Name, null, null / LOAD DLL on our application loaded Dll List. Add(dll Name Thank you.
I faced a similar situation. It's rare that I actually need the location, but for the cases that I do, I created a helper class ( Assembly Utilities) that I use to load the bytes for the assembly and just store the location in a static Dictionary. An additional helper method ( Get Location) peeks through to the assembly's actual location, and if there isn't one, consults the dictionary. This works fine since I'm responsible for loading the raw bytes anyway, and the peek-through handles assemblies loaded in the traditional way. Like so. public static class Assembly Utilities private static Dictionary< Assembly, string> location By Assembly = new Dictionary< Assembly, string> private static Dictionary assembly By Location = new Dictionary( String Comparer. Ordinal Ignore Case public static Assembly Load File(string location) Assembly assembly; lock (location By Assembly) if (!assembly By Location. Try Get Value(location, out assembly) byte[] bytes = Read All Bytes(location if (bytes = null) return null; byte[] pdb = Read All Bytes( Path. Change Extension(location.pdb assembly = (pdb = null)? Assembly. Load(bytes Assembly. Load(bytes, pdb location By Assembly[assembly] = location; assembly By Location[location] = assembly; return assembly; public static string Get Location( Assembly assembly) if (assembly = null) return null; string location = assembly. Location; if (location = null) location By Assembly. Try Get Value(assembly, out location return location; private static byte[] Read All Bytes(string path) try return File. Read All Bytes(path catch return null; / And if you prefer extensions. public static class Assembly Extensions public static string Get Location(this Assembly self) return Assembly Utilities. Get Location(self.
Load Method ( Byte[]) Load Method ( Byte[]) Load Method ( Byte[], Byte[]) Load Method ( Byte[], Byte[], Evidence) Load Method ( Byte[], Byte[], Security Context Source) Load Method ( Assembly Name) Load Method ( Assembly Name, Evidence) Load Method ( String) Load Method ( String, Evidence) TOC Collapse the table of content Expand the table of content. NET Framework (current version) Other Versions. NET Framework 4. NET Framework 3.5. NET Framework 3.0. NET Framework 2.0  Loads the assembly with a common object file format ( COFF)-based image containing an emitted assembly. The assembly is loaded into the application domain of the caller. Namespace:   System. Reflection Assembly:  mscorlib (in mscorlib.dll) Syntax C C+ F VB Copy public static Assembly Load( byte[] raw Assembly ) raw Assembly Type: System. Byte[] A byte array that is a COFF-based image containing an emitted assembly. Type: System. Reflection. Assembly The loaded assembly. Exceptions Exception Condition Argument Null Exceptionraw Assembly is null. Bad Image Format Exceptionraw Assembly is not a valid assembly. -or- Version 2.0 or later of the common language runtime is currently loaded and raw Assembly was compiled with a later version. Remarks The trust level of an assembly that is loaded by using this method is the same as the trust level of the calling assembly. To load an assembly from a byte array with the trust level of the application domain, use the Load( Byte[], Byte[], Security Context Source) method overload. For more information about the use of evidence with overloads of the Load method that take byte arrays, see the Load( Byte[], Byte[], Evidence) method overload. Reflecting on C+ executable files might throw a Bad Image Format Exception. This is most likely caused by the C+ compiler stripping the relocation addresses or the.reloc section from your executable file. To preserve the.reloc address for your C+ executable file.
I don't suggest embedding the vendor assemblies in yours for a couple of reasons. First, not all device vendor SDKs are pure. NET that can or should be plopped down in the app folder. Many require their install to be run to put standard dlls, registry entries, and the like in place. Secondly, you are increasing the size of your component by embedding each vendors assemblies in your middleware and, assuming that you are supporting multiple vendors, the size could get quite large. Especially if the device already has the scanning Assemblies in the GAC, you are taking extra storage you didn't need to at all. I use, and suggest, the following mechanism: Application(s). |. V. Generic scanning abstraction lib. ( Assembly. Load From based A. upon convention or XML |. configuration file) Vendor Specific Implementation of abstraction <. | V Vendor SDK In this way, you setup your plugins at CAB creation time including the information to dynamically load them based on a config file or other naming convention. The app does know or care which implementation of the abstraction gets loaded, only that it conforms to the abstraction.
I'm experimenting with loading an assembly using just byte arrays, but I can't figure out how to get it to work properly. Here is the setup: public static void Main Permission Set permissions = new Permission Set( Permission State. None App Domain Setup setup = new App Domain Setup Application Base = Environment. Current Directory ; App Domain friendly Domain = App Domain. Create Domain( Friendly, null, setup, permissions Byte[] primary = File. Read All Bytes( Primary.dll_ Byte[] dependency = File. Read All Bytes( Dependency.dll_ / Crashes here saying it can't find the file. friendly Domain. Load(dependency App Domain. Unload(friendly Domain Console. Write Line( Stand successful Console. Read Line I created two mock dlls, and renamed their extension to '.dll intentionally so the system wouldn't be able to find the physical files. Both primary and dependency fill correctly, but when I try to call the App Domain. Load method with the binary data, it comes back with: Could not load file or assembly ' Dependency, Version=, Culture=neutral, Public Key Token=null' or one of its dependencies. The system cannot find the file specified. Why would it be searching the system for a file? UPDATE This on the other hand seems to work: public class Program public static void Main Permission Set permissions = new Permission Set( Permission State. Unrestricted App Domain Setup setup = new App Domain Setup Application Base = Environment. Current Directory ; App Domain friendly Domain = App Domain. Create Domain( Friendly, null, setup, permissions Byte[] primary = File. Read All Bytes( Primary.dll_ Byte[] dependency = File. Read All Bytes( Dependency.dll_ / Crashes here saying it can't find the file. / friendly Domain. Load(primary Stage stage = ( Stage)friendly Domain. Create Instance And Unwrap(typeof( Stage). Assembly. Full Name, typeof( Stage). Full Name stage. Load Assembly(dependency Console. Write Line(.
As I understand it, you want to do the following: Load an assembly from disk, into memory, in order to use data in it, or call code in it Be able to unload the assembly later on Avoid locking the assembly on disk, so that you can modify it without having to exit the application (or unload the assembly first) Basically, what you're describing is a plugin system of sorts, and you can do that with the usage of shadowed dll's and application domains. First, in order to unload an assembly, without just exiting the application, you need to load that assembly into a separate application domain. You should be able to find good tutorials on the net on how to do that. Here's a Google query that should provide you with some starting articles. Secondly, in order to avoid locking the assembly on disk, that's simple, just make a copy of it first, and load the copy instead of the original. Sure, you'll lock the copy, but the copy is just a temp file for your application so nobody should be interested in modifying that file anyway. This leaves the original file unlocked and modifiable. You should try to make use of shadowing instead of using the overloads of Assembly. Load that can load assemblies from a byte array if you have more than one assembly that will be loaded and replaced. For instance, if your plugin assembly A.dll relies on a second assembly B.dll, and you use the byte array trick to load A.dll into memory before calling Assembly. Load, you need to either handle assembly resolution calls in your app domain (you can be told whenever an assembly needs to be loaded, and help the loading process or you need to make sure B.dll is loaded first the same way A.dll is loaded, otherwise loading A.dll from memory will automatically load B.dll from disk. Here's some more information about using separate application domains. When you create another application domain, through the.