title: Load a WPF application Assembly from another WPF app, get error: Cannot create more than one System.Windows.Application instance in the same AppDomain
body: <p>The Scenario:</p>
  
  <p><strong>LUNCHER.exe</strong>:   a WPF Application >> <code>Build 32bit</code>, <code>.Net 4.5.1</code>, <code>location= D:\</code></p>
  
  <p><strong>LOADED.exe</strong>:    another WPF Application >> <code>Build 32bit</code>, .Net 4.5.1, <code>location= D:\</code></p>
  
  <p>I'm <code>owner of both assembly</code> (both application and thair sources)</p>
  
  <p>Now, i want load the <code>LOADED.exe</code> [and its resources such as images dlls and...) as a <code>Byte array</code> to the memory and execute it, then remove <code>LOADED.exe</code> and its resources from hard disk.</p>
  
  <p>In the first step i'm trying to <code>just load the LOADED.exe file to memory and execute it</code> (so i used a <code>simple EXE without any resource</code> in this step).</p>
  
  <h2><strong>A)</strong></h2>
  
  <p>Ok, i found this way for WinForm programes <a href="http://www.codeproject.com/Articles/13897/Load-an-EXE-File-and-Run-It-from-Memory" rel="nofollow noreferrer">here</a>:</p>
  
  <pre><code>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?
      }
  }
  </code></pre>
  
  <p>I tried it inside LUNCHER.exe under a button then RUN... The result of handled exception:</p>
  
  <blockquote>
    <p><strong>Cannot create more than one System.Windows.Application instance in the same AppDomain.</strong></p>
  </blockquote>
  
  <p><img src="https://i.stack.imgur.com/sB2YO.png" alt="enter image description here"></p>
  
  <p>OK!</p>
  
  <hr>
  
  <h2><strong>B)</strong></h2>
  
  <p>Then, i searched for a solution and some body has been said you must execute it in a <code>new [different] AppDomain</code>.</p>
  
  <p>For example here is an answer: <a href="https://stackoverflow.com/questions/16755882/dynamically-loaded-assembly-settings-communication#17022969">Dynamically Loaded Assembly - Settings &amp; Communication</a></p>
  
  <p>I tried it by the following codes under another button in the <code>LUNCHER.exe</code>:</p>
  
  <pre><code>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&gt;&gt;
          return appDomain.CreateInstanceFromAndUnwrap(assemblyPath, method.Name); 
      }
      else
      {
          return appDomain.CreateInstanceFromAndUnwrap(assemblyPath, className);
      }
  }
  </code></pre>
  
  <p>Now my error is in this line:
  <img src="https://i.stack.imgur.com/L1dI5.png" alt="enter image description here"></p>
  
  <p>OK!</p>
  
  <hr>
  
  <h2><strong>C)</strong></h2>
  
  <p>I searched again and found this one (<a href="https://stackoverflow.com/questions/22641191/dynamically-loaded-assembly-not-loading-in-new-appdomain#22641969">Dynamically loaded Assembly not loading in new AppDomain</a>): </p>
  
  <pre><code>// 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;
          }
      }
  }
  </code></pre>
  
  <p>Then i called it by the following codes under another button in the <code>LUNCHER.exe</code>:</p>
  
  <pre><code>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[] {});
  }
  </code></pre>
  
  <p>But i get same error like previous way <code>**B**</code>:</p>
  
  <blockquote>
    <p>An unhandled exception of type 'System.TypeLoadException' occurred in
    Luncher.exe</p>
    
    <p>Additional information: <strong>Could not load type 'Main' from assembly
    Loaded, Version=1.0.0.0, Culture=neutral,
    PublicKeyToken=null'</strong>.</p>
  </blockquote>
  
  <hr>
  
  <h2><strong>D)</strong></h2>
  
  <p>Also i tested this way under another button in the <code>LUNCHER.EXE</code>:</p>
  
  <pre><code>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);
  
      //fix urihelper
      var helper = typeof (BaseUriHelper);
      var property = helper.GetProperty("ResourceAssembly", BindingFlags.NonPublic | BindingFlags.Static);
      property.SetValue(null, assembly, null);
  
      //---- Now my ERROR is in this line &gt;&gt;
      assembly.EntryPoint.Invoke(null, new object[] {});
  }
  </code></pre>
  
  <p>And error in last line of code in Run Time:</p>
  
  <blockquote>
    <p>An unhandled exception of type
    '<strong>System.Reflection.TargetInvocationException</strong>' occurred in mscorlib.dll</p>
    
    <p>Additional information: <strong>Exception has been thrown by the target of an
    invocation.</strong></p>
  </blockquote>
  
  <hr>
  
  <h2>Finally:</h2>
  
  <p>I'm confused!</p>
  
  <ul>
  <li>what is my mistake in all above methods?</li>
  <li>why all the ways end with an ERROR!!!</li>
  </ul>
  
  <p>Please help me with simple descriptions and some codes because I'm beginner in this scenarios (loading assembly, create <code>AppDomain</code> and...) but i need to load a WPF application to the memory and show its window and then delete it's file from H.D.D while it is running in the memory. </p>