Frage

Hier ist das Kernproblem: Ich habe eine .NET-Anwendung, die COM-Interop in a verwendet separater AppDomain. Die COM Sachen scheint Baugruppen wieder in die Standarddomäne zu laden, anstatt die AppDomain, aus dem die COM Sachen aufgerufen wird.

Was ich wissen möchte, ist: ist das erwartete Verhalten, oder bin ich etwas falsch machen diese COM bezogenen Baugruppen verursachen in der falschen AppDomain geladen werden? Bitte beachten Sie eine detailliertere Beschreibung der Situation unter ...

Die Anwendung besteht aus drei Baugruppen: - die wichtigsten EXE, der Einstiegspunkt der Anwendung. - common.dll, enthält nur eine Schnittstelle IRegler (im IPlugin Stil) - controller.dll, enthält eine Controller-Klasse, die IRegler und MarshalByRefObject implementiert. Diese Klasse macht die ganze Arbeit und verwendet COM-Interop mit einer anderen Anwendung zu interagieren.

Der relevante Teil des Haupt EXE sieht wie folgt aus:

AppDomain controller_domain = AppDomain.CreateDomain("Controller Domain");
IController c = (IController)controller_domain.CreateInstanceFromAndUnwrap("controller.dll", "MyNamespace.Controller");
result = c.Run();
AppDomain.Unload(controller_domain);

Die common.dll enthält nur diese 2 Dinge:

public enum ControllerRunResult{FatalError, Finished, NonFatalError, NotRun}
public interface IController
{
    ControllerRunResult Run();
}

Und die controller.dll enthält diese Klasse (die auch die COM-Interop-Sachen ruft):

public class Controller: IController, MarshalByRefObject

Beim ersten Ausführen der Anwendung, Assembly.GetAssemblies () sieht wie erwartet, mit common.dll in beiden AppDomains geladen und controller.dll nur in die Controller Domäne geladen. Nach dem Aufruf von c.Run () aber ich sehe, dass auf das COM-Interop-Material im Zusammenhang Baugruppen ist in das Standard-AppDomain geladen worden ist, und nicht in der AppDomain, aus dem das COM-Interop stattfindet.

Warum kann dies vorkommen werden?

Und wenn Sie daran interessiert sind, hier ist ein wenig Hintergrund:

Ursprünglich war dies eine 1 AppDomain Anwendung. Die COM stopft es eine Schnittstelle mit ist ein Server-API, die nicht stabil über lange Zeiträume verwendet wird. Wenn ein COMException (ohne nützliche diagnostische Informationen über seine Ursache) aus den COM Sachen auftritt, hat die gesamte Anwendung neu gestartet, bevor die COM-Verbindung wieder funktioniert. Einfach Wiederverbindung wieder auf den COM-App-Server führt zur sofortigen COM Ausnahmen. Um dies zu bewältigen habe ich versucht, um das COM-Interop-Material in einen separaten AppDomain zu bewegen, so dass, wenn die Rätsel COMExceptions auftreten kann ich die AppDomain entladen, in dem sie auftritt, erstellen Sie einen neuen und wieder von vorn anfangen, alle, ohne manuell die Anwendung neu starten . Das war die Theorie sowieso ...

War es hilfreich?

Lösung

Leider ist eine COM-Komponente in Prozessraum geladen und nicht im Rahmen eines AppDomain. Daher müssen Sie manuell -abbau (Release und Unload) Mutter DLLs (gilt sowohl für COM und P / Invoke). Einfach eine Appdomain zerstören wird dir nicht gut, aber den gesamten Prozess respawning sollte nicht notwendig sein, um COM-Zustand zurückgesetzt werden (einfach das COM-Objekt (e) neu zu erstellen sollte auch normal arbeiten, das klingt wie ein Fehler in der Code-Komponente-Anbieter, vielleicht sie können es lösen?)

Referenzen

(TechNet) Prozessadressraum

(MSDN) Anwendungsdomänen

(MSDN) Grenzen: Prozesse und AppDomains

Andere Tipps

Hier ist der Beweis dafür, dass Shaun Wilson Antwort richtig ist

Com App Domain

Lassen Sie Ihren Controller-MBR nicht. Erstellen Sie eine kleine Proxy, der den Controller in der zweiten Domäne lädt und startet es. Auf diese Weise Controller-DLL wird in der ersten Domäne nicht geladen werden.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top