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:
AppDomain.Load
carica un assembly myDomain
corrente e non su myDomain
(strano, lo so). 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);