Scenario:
LUNCHER.exe : WPF application → Build 32bit , .Net 4.5.1 , location= D:\
LOADED.exe : another WPF application -> Build 32bit , .Net 4.5.1, location= D:\
I am the owner of both assembly (both applications and tag sources)
Now I want to load LOADED.exe [and its resources, such as DLL images and ...), like the Byte array into memory and execute it, and then delete LOADED.exe and its resources from the hard drive.
In the first step, I try just load the LOADED.exe file to memory and execute it (so I used simple EXE without any resource in this step).
A)
Ok, I found this method for WinForm programs here :
var filePath = @"D:\LOADED.EXE"; if (File.Exists(filePath)) { try { // prepare to load the application into memory (using Assembly.Load) // read the bytes from the application exe file var fs = new FileStream(filePath, FileMode.Open); var br = new BinaryReader(fs); byte[] bin = br.ReadBytes(Convert.ToInt32(fs.Length)); fs.Close(); br.Close(); // load the bytes into Assembly var asm = Assembly.Load(bin); // search for the Entry Point var method = asm.EntryPoint; if (method != null) { // create an istance of the Startup form Main method object o = asm.CreateInstance(method.Name); // invoke the application starting point Application.Current.ShutdownMode = System.Windows.ShutdownMode.OnExplicitShutdown; method.Invoke(o, null); } else { //show message: Impossible to launch the application } } catch(Exception ex) { MessageBox.Show(ex.Message + "\n\r\n\r" + ex.InnerException + "\n\r\n\r" + "\n\r\n\r" + ex.Source); // exception throws .. something to do? } }
I tried it inside LUNCHER.exe under the button, then RUN ... The result of the processed exception:
Unable to create multiple instances of System.Windows.Application in the same AppDomain.

OK!
IN)
Then I searched for a solution, and some body was told that you should execute it in the new [different] AppDomain .
For example, here is the answer: Dynamically loaded assembly - settings and communication
I tried it using the following codes under another button in LUNCHER.exe :
private void Button_Click_1(object sender, RoutedEventArgs e) { try { var filePath = string.Format("{0}{1}", Utility.ExePath, PART_PATH); AppDomain newappdomain = getAppDomainForAssembly(filePath, "LOADED.exe.domain"); object loadedexe_object = getInstanceFromAppDomain(ref newappdomain, filePath); //If you know the method name to call... executeMethod(loadedexe_object.GetType(), "methodname", ref loadedexe_object, null); //or get entry point... executeMethod(loadedexe_object.GetType(), _asm_resolve(filePath).EntryPoint.Name, ref loadedexe_object, null); } catch (Exception ex) { var type = ""; if (ex is ArgumentNullException) { type = "ArgumentNullException"; } else if (ex is NotSupportedException) { type = "NotSupportedException"; } else if (ex is AppDomainUnloadedException) { type = "AppDomainUnloadedException"; } else if (ex is TypeLoadException) { type = "TypeLoadException"; } else if (ex is MissingMethodException) { type = "MissingMethodException"; } else if (ex is MethodAccessException) { type = "MethodAccessException"; } else if (ex is BadImageFormatException) { type = "BadImageFormatException"; } else if (ex is FileLoadException) { type = "FileLoadException"; } MessageBox.Show(type + "\n\r\n\r" + ex.Message + "\n\r\n\r" + ex.InnerException + "\n\r\n\r" + ex.Source); } } private AppDomain getAppDomainForAssembly(string assemblypath, string appdomainname) { //this._assembly_file = AssemblyFile; string _assembly_file_name = System.IO.Path.GetFileName(assemblypath); string _rootpath = System.IO.Path.GetDirectoryName(assemblypath); //this._assembly_class_name = AssemblyClassNameToInstance; AppDomainSetup _app_domain_info = new AppDomainSetup(); _app_domain_info.ApplicationBase = _rootpath; _app_domain_info.PrivateBinPath = _rootpath; _app_domain_info.PrivateBinPathProbe = _rootpath; _app_domain_info.ConfigurationFile = _rootpath + @"LOADED.exe.config"; //Here put the path to the correct .assembly .config file AppDomain _app_domain = AppDomain.CreateDomain(appdomainname, null, _app_domain_info); return _app_domain; } protected System.Reflection.Assembly _asm_resolve(string assemblyFile) { return System.Reflection.Assembly.LoadFrom(assemblyFile); } private object getInstanceFromAppDomain(ref AppDomain appDomain, string assemblyPath, string className = null) { if (string.IsNullOrEmpty(className)) { System.Reflection.Assembly assembly = _asm_resolve(assemblyPath); System.Reflection.MethodInfo method = assembly.EntryPoint; // Now my ERROR is in this line>> return appDomain.CreateInstanceFromAndUnwrap(assemblyPath, method.Name); } else { return appDomain.CreateInstanceFromAndUnwrap(assemblyPath, className); } }
Now my error is on this line: 
OK!
FROM)
I searched again and found this ( Dynamically loaded collector did not load into the new AppDomain ):
// Provides a means of invoking an assembly in an isolated appdomain public static class IsolatedInvoker { // main Invoke method public static void Invoke(string assemblyFile, string typeName, string methodName, object[] parameters) { // resolve path assemblyFile = Path.Combine(Environment.CurrentDirectory, assemblyFile); Debug.Assert(assemblyFile != null); // get base path var appBasePath = Path.GetDirectoryName(assemblyFile); Debug.Assert(appBasePath != null); // change current directory var oldDirectory = Environment.CurrentDirectory; Environment.CurrentDirectory = appBasePath; try { // create new app domain var domain = AppDomain.CreateDomain(Guid.NewGuid().ToString(), null, appBasePath, null, false); try { // create instance var invoker = (InvokerHelper) domain.CreateInstanceFromAndUnwrap(Assembly.GetExecutingAssembly().Location, typeof(InvokerHelper).FullName); // invoke method var result = invoker.InvokeHelper(assemblyFile, typeName, methodName, parameters); // process result Debug.WriteLine(result); } finally { // unload app domain AppDomain.Unload(domain); } } finally { // revert current directory Environment.CurrentDirectory = oldDirectory; } } // This helper class is instantiated in an isolated app domain private class InvokerHelper : MarshalByRefObject { // This helper function is executed in an isolated app domain public object InvokeHelper(string assemblyFile, string typeName, string methodName, object[] parameters) { // create an instance of the target object var handle = Activator.CreateInstanceFrom(assemblyFile, typeName); // get the instance of the target object var instance = handle.Unwrap(); // get the type of the target object var type = instance.GetType(); // invoke the method var result = type.InvokeMember(methodName, BindingFlags.InvokeMethod | BindingFlags.Public | BindingFlags.Instance, null, instance, parameters); // success return result; } } }
Then I called it the following codes under another button in LUNCHER.exe :
private void Button_Click_2(object sender, RoutedEventArgs e) { var filePath = string.Format("{0}{1}", Utility.ExePath, PART_PATH); IsolatedInvoker.Invoke(filePath, "Main", "Main", new object[] {}); }
But I get the same error as the previous method **B** :
An unhandled exception of type "System.TypeLoadException" occurred in Luncher.exe
Additional information: Failed to load type "Main" from the Loaded assembly, Version = 1.0.0.0, Culture = neutral, PublicKeyToken = NULL .
D)
I also tested this path under another button in LUNCHER.exe :
private void Button_Click_3(object sender, RoutedEventArgs e) { var filePath = @"D:\LOADED.exe"; var dll = File.ReadAllBytes(filePath); var assembly = Assembly.Load(dll); var app = typeof (Application); var field = app.GetField("_resourceAssembly", BindingFlags.NonPublic | BindingFlags.Static); field.SetValue(null, assembly);
And the error in the last line of code at runtime:
An unhandled exception of type ' System.Reflection.TargetInvocationException "occurred in mscorlib.dll
Additional information: An exception was chosen as the target of the call.
Finally:
I'm confused!
- What is my mistake in all of the above methods?
- why all the paths end in ERROR !!!
Please help me with simple descriptions and some codes, because I start in these scenarios (loading the assembly, create the AppDomain and ...), but I need to load the WPF application into memory and show its window, and then delete it from the hard drive while it is running in memory.