Creare AppDomain personalizzato e aggiungervi assembly

Come posso creare un appdomain, aggiungere assembly ad esso, quindi distruggere il dominio dell’app? Questo è quello che ho provato:

static void Main(string[] args) { string pathToExe = @"A:\Users\Tono\Desktop\ConsoleApplication1.exe"; AppDomain myDomain = AppDomain.CreateDomain("MyDomain"); Assembly a = Assembly.Load(System.IO.File.ReadAllBytes(pathToExe)); myDomain.Load(a.FullName); // Crashes here! } 

Ho anche provato:

 myDomain.Load(File.ReadAllBytes(pathToExe)); 

come posso aggiungere un assembly all’appdomain. Una volta fatto ciò, posso trovare il metodo tramite reflection eseguirlo e quindi distruggere l’appdomain

L’eccezione che ottengo è:

Imansible caricare il file o l’assembly ‘ConsoleApplication1, Version = 1.0.0.0, Culture = neutral, PublicKeyToken = null’ o una delle sue dipendenze. Il sistema non trova il file specificato.

Due punti veloci:

  1. AppDomain.Load carica un assembly myDomain corrente e non su myDomain (strano, lo so).
  2. AppDomain.Load carica un assembly nel contesto Load , che risolve gli assembly dalla directory di base dell’app, i percorsi private-bin e il GAC. Molto probabilmente, l’assembly che si tenta di caricare non si trova in nessuna di queste posizioni, il che spiega il messaggio di eccezione.

Per maggiori informazioni dai un’occhiata a questa risposta .

Un modo per caricare gli assembly in un AppDomain è creare un caricatore derivato da MarshalByRef. Hai bisogno di qualcosa di simile per evitare perdite di tipi (e assemblaggi) al tuo AppDomain principale. Ecco una semplice:

 public class SimpleAssemblyLoader : MarshalByRefObject { public void Load(string path) { ValidatePath(path); Assembly.Load(path); } public void LoadFrom(string path) { ValidatePath(path); Assembly.LoadFrom(path); } private void ValidatePath(string path) { if (path == null) throw new ArgumentNullException("path"); if (!System.IO.File.Exists(path)) throw new ArgumentException(String.Format("path \"{0}\" does not exist", path)); } } 

E usalo in questo modo:

 //Create the loader (a proxy). var assemblyLoader = (SimpleAssemblyLoader)myDomain.CreateInstanceAndUnwrap(typeof(SimpleAssemblyLoader).Assembly.FullName, typeof(SimpleAssemblyLoader).FullName); //Load an assembly in the LoadFrom context. Note that the Load context will //not work unless you correctly set the AppDomain base-dir and private-bin-paths. assemblyLoader.LoadFrom(pathToExe); //Do whatever you want to do. //Finally unload the AppDomain. AppDomain.Unload(myDomain);