Laden...

Aktive Instanz einer Windows.Forms Anwendung ermitteln (von hinten durch das Auge)

Erstellt von Seikilos vor 13 Jahren Letzter Beitrag vor 13 Jahren 2.688 Views
S
Seikilos Themenstarter:in
753 Beiträge seit 2006
vor 13 Jahren
Aktive Instanz einer Windows.Forms Anwendung ermitteln (von hinten durch das Auge)

Es gibt eine Anwendung A, welche eine Form instantiiert und desweiteren ein Plugin, dynamisch zur Laufzeit lädt, welches ein Interface implementiert.

Ich befinde mich im Scope des Plugins und kenne erstmal nicht die Elternanwendung und habe keine Referenzen darauf bei der Erzeugung des Plugins.
Also sprich kein new MeinPlugin(this);
Das Plugin kennt also seinen Kontext nicht.

Mein Problem an dieser Stelle: Ich benötige diesen Kontext.
Gibt es einen Weg aus dem Plugin (DLL) die Form der Anwendung A zu bekommen?

Vom Konzept her ist es unsauber, dessen bin ich mir bewusst. Ich versuche nur zu prüfen, ob ich über Reflection an die aktuelle Instanz rankomme oder nicht.
Die Typinformation von der Form da oben habe ich bereits durch das Einbinden der Anwendung A Assembly, ich finde nur keinen Weg, mir die Instanz zu holen.

Ich krieg über Reflection den Stack und die Methode, aber nicht die Instanz selbst, hmmm

Life is a short

22 Beiträge seit 2010
vor 13 Jahren

Ja, das ist möglich:

Wir implementieren einen Singleton-Pattern im Formular:


#region singleton implementation
        private static volatile F_Plugins instance;
        private static object syncRoot = new Object();
        public static F_Plugins Instance
        {
            get
            {
                if (instance == null || instance.IsDisposed)
                {
                    lock (syncRoot)
                    {
                        if (instance == null || instance.IsDisposed)
                            instance = new F_Plugins();
                    }
                }

                return instance;
            }
        }
        #endregion

Im "Plugin" sagen wir nun:


Assembly lEntryAssembly = Assembly.GetEntryAssembly();
            Type[] lExportedTypes = lEntryAssembly.GetExportedTypes();
            
            foreach (Type lType in lExportedTypes)
            {
                if (lType.Name == "F_Plugins")
                {
                    Form lForm = (Form)lType.GetProperty("Instance").GetValue(lType, null);
                    lForm.Text = "Test123";
                    break;
                }
            }

Ich habe mir die Lösung gerade erst ausgedacht da ich sowas sicherlich auch mal bracuhen werde. Es ist unsauber an vielen stellen und wenn man damit richtig arbeiten möchte gibt es sicherlich noch optimierungsbedarf (ggf über ein eigenes Interface für "F_Plugin") dann kann man sich den weg über Reflection sparen.

Funktionieren tut es - gross getestet habe ich es aber nicht.

Ich weis nicht ob man Forms einen Singleton-Pattern reindrücken "sollte" ich finde es aber in vielen fällen einfach praktisch wenn man das Formular sowiso nur maximal 1x benutzen möchte.

Weitere Informationen zu Singleton-Patterns findest du hier:
http://en.wikipedia.org/wiki/Singleton_pattern#C.23

HAI
 CAN HAS STDIO?
 PLZ OPEN FILE "LOLCATS.TXT"?
     AWSUM THX
         VISIBLE FILE
     O NOES
         INVISIBLE "ERROR!"
 KTHXBYE
49.485 Beiträge seit 2005
vor 13 Jahren

Hallo Seikilos,

Process.GetCurrentProcess ().MainWindowHandle

herbivore

22 Beiträge seit 2010
vor 13 Jahren

Wenn du nur mit dem Hauptformular arbeiten möchtest funktioniert das auch 😉

Form lTestForm = (Form)Control.FromHandle(Process.GetCurrentProcess().MainWindowHandle);

auch gerade ausprobiert 😉

HAI
 CAN HAS STDIO?
 PLZ OPEN FILE "LOLCATS.TXT"?
     AWSUM THX
         VISIBLE FILE
     O NOES
         INVISIBLE "ERROR!"
 KTHXBYE
S
Seikilos Themenstarter:in
753 Beiträge seit 2006
vor 13 Jahren

Process.GetCurrentProcess ().MainWindowHandle liefert mir null.

Das habe ich bereits probiert. Aber wenn ihr das auch vorschlagt, dann sollte es wohl nicht null, oder?

Das Singleton von Myth erfordert die Anpassung des Host codes, was hier ja nicht möglich ist.

Danke

Life is a short

49.485 Beiträge seit 2005
vor 13 Jahren

Hallo Seikilos,

es ist nicht sichergestellt, dass eine Anwendung auch ein Hauptfenster hat. Da sind wird dann wieder bei: "Vom Konzept her ist es unsauber". Man kann halt keine verlässliche Aussagen über eine undefinierte Umgebung machen.

herbivore

S
Seikilos Themenstarter:in
753 Beiträge seit 2006
vor 13 Jahren

Ich denke das Problem bei mir ist, dass die Form die Plugins im new von sich selbst lädt. Sprich das Plugin ist da bevor die Form bereit ist. Hmmmf.

Danke für die Hilfe

Life is a short

T
381 Beiträge seit 2009
vor 13 Jahren

Dann kannst du ja zu späterem Zeitpunkt die obige methode aufrufen. Wenn sie das erste mal wirklich gebraucht wird, oder (noch unsauberer) nach Ablauf eines Timer.

5.299 Beiträge seit 2008
vor 13 Jahren

kann das plugin nicht ein Event werfen, welches im A.Mainwindow verarbeitet wird?

Der frühe Apfel fängt den Wurm.

S
Seikilos Themenstarter:in
753 Beiträge seit 2006
vor 13 Jahren

Nö. Auf A habe ich kein Zugriff, aber A wirft andere Events, an die ich mich probehalber anhängen kann, dann ist der Ctor der Form schon durch und ist verfügbar

Life is a short

T
381 Beiträge seit 2009
vor 13 Jahren

Vielleicht noch irgendwas per Reflection?

S
Seikilos Themenstarter:in
753 Beiträge seit 2006
vor 13 Jahren

Was eventuell interessant wäre: Ist es möglich per Reflection eine Methode aus einer anderen Assembly zu überladen oder sich da reinzuhängen?

Die Hauptanwendung hat update routinen, die keine Events oder etwas in der Art feuern, wenn sie beendet worden sind. Ich muss aber nach dem Update zusätzliche Operationen ausführen, die immer nach dem Update ausgeführt werden müssen.

Problem ist: Mein Plugin kriegt nicht mit, wann das Update durchgeführt worden ist

Life is a short

49.485 Beiträge seit 2005
vor 13 Jahren

Hallo Seikilos,

ich muss aber nach dem Update zusätzliche Operationen ausführen

Problem ist: Mein Plugin kriegt nicht mit, wann das Update durchgeführt worden ist

womit wir wieder beim Design wären. Wenn es notwendig ist, dass Plugins nach dem Update informiert werden, dann sollte die Hostanwendung die Plugins informieren.

herbivore

S
Seikilos Themenstarter:in
753 Beiträge seit 2006
vor 13 Jahren

Jepp, keine Frage.
Das wird durchaus auch passieren.
Aber aktuell ist es noch nicht passiert und der Host kann im Moment nicht geändert werden.

Das soll auch kein Produktivcode werden, sondern eher ein Proof of Concept des Plugins.
Die Leute, die sich das angucken, verstehen nichts von Callbacks oder ähnlichem, sondern brauchen quasi ne visuelle Demo

Life is a short