2016-11-16 4 views
0

Ich versuche, einige Metadaten einer Assembly zu überprüfen, ohne sie (dauerhaft) in meine App zu laden. Um dies zu tun, erstelle ich eine temporäre sandbox AppDomain, laden Sie die Baugruppe hinein und entladen Sie dann die gesamte sandbox. Laut den Antworten auf this question ist das "richtige" Weg, es zu tun.AppDomain.Unload entfernt Assemblys nicht

Allerdings bleibt es nach dem Entladen der Baugruppe in der aktuellen AppDomain. Warum?

Die Antwort auf this question vorschlagen, dass die Assembly in die aktuelle Domäne "ausgeblutet" werden kann, aber ich sehe nicht, wie das in meinem Beispiel möglich sein kann. Der Rest der Anwendung verwendet die Assembly überhaupt nicht, es ist nicht einmal referenziert. Das beobachtete Verhalten bleibt bestehen, auch wenn ich die sandobx sofort nach der Montage Last entladen.

This article besagt, dass Domänen-neutrale Assemblys auf diese Weise nicht entladen werden können. Ist das der Grund? Wenn ja, kann ich irgendwie verhindern, dass die Assembly als domänenneutral behandelt wird?

private void Check() 
{ 
    string assemblyName = "SomeUnrelatedAssembly"; 
    var sandbox = AppDomain.CreateDomain("sandbox"); //create a discardable AppDomain 
    //load the assembly to the sandbox 
    byte[] arr; 
    using (var memoryStream = new MemoryStream()) 
    { 
     using (var fileStream = new FileStream($"{assemblyName}.dll", FileMode.Open)) 
      fileStream.CopyTo(memoryStream); 
     arr = memoryStream.ToArray(); 
    } 

    Console.WriteLine(IsAssemblyLoaded(assemblyName)); //prints false 
    sandbox.Load(arr); 

    //and unload it  
    AppDomain.Unload(sandbox);  
    Console.WriteLine(IsAssemblyLoaded(assemblyName)); //prints true! 
} 

private static bool IsAssemblyLoaded(string assemblyName) 
{ 
    return AppDomain.CurrentDomain.GetAssemblies().Any(a => a.FullName.Contains(assemblyName)); 
} 

EDIT: Ich habe den Ladevorgang mit Process Explorer überprüft (wie this). Die geladene Assembly ist NICHT domänenneutral.

+0

können Sie zeig uns was '// check som Der Metadaten-Code sieht so aus? Es ist möglich, dass Sie Metadaten in der aktuellen Domäne durchgehen, obwohl Sie Assembly in einer Sandbox-Domäne laden. –

+0

Das Verhalten ist dasselbe, auch wenn zwischen den Anweisungen 'sanbox.Load' und' AppDomain.Unload' nichts ist. – tearvisus

Antwort

0

Sie haben Recht. Ihre Assembly wird als domänenneutral betrachtet und in App-Domains geteilt.

die AppDomain.CreateDomain Überlastung, die Sie Setup-Informationen bieten können:

Info:

AppDomainSetup info = new AppDomainSetup(); 
info.ApplicationBase = domainDir; 
info.ApplicationName = executableNameNoExe; 
info.LoaderOptimization = LoaderOptimization.SingleDomain; 

Wechsel:

AppDomain.CreateDomain("sandbox"); 

An:

AppDomain.CreateDomain("sandbox",null, info); 
+0

Leider funktioniert es nicht. Der zweite Test gibt immer noch True aus. – tearvisus

+0

Was ist, wenn 'IsAssemblyLoaded() 'vor' Check' Anruf aufrufen? Kann sein Es wurde früher geladen? –

+0

Mit der 'zweiten Überprüfung' meinte ich den zweiten 'IsAssemblyLoaded'-Aufruf. Die Methode 'Check' in diesem Beispiel wird genau einmal aufgerufen. – tearvisus