Announcement

Collapse
No announcement yet.

Plugins entladen

Collapse
X
  • Filter
  • Time
  • Show
Clear All
new posts

  • Plugins entladen

    Hallo zusammen,

    meine Anwendung arbeitet mit Plugins. Mir ist aufgefallen das der IE z.B. weiterläuft während ein Plugin ein update erhält. Wie kann ich meine Plugins entladen damit ich sie löschen und ersetzen kann?
    Per Appdomain lade ich die Assemblys, nur wenn ich diese dann mit AppDomain.Unload entlade, kann ich nicht darauf zugreifen....

    MfG
    Die Taschenlampe!

    Die perfekte Taschenlampe für Ihr Windows Phone!

    - Die APP steuert die echte Blitz-LED an und versorgt Sie mit 100% Leistung!
    - Zudem zeigt die Live-Kachel den aktuellen Akkustand des Telefons an!


    Hier gehts zu APP!

  • #2
    Von wo (welcher AppDomain) und wie rufst du das entsprechende Assembly.Load auf?

    Comment


    • #3
      Hallo,

      eine alternative Möglichkeit wäre Shadow Copying of Applications und dann das PlugIn neu laden. So macht es z.B. ASP.net auch.

      mfG Gü
      "Any fool can write code that a computer can understand. Good programmers write code that humans can understand". - Martin Fowler

      Comment


      • #4
        Hi!

        Die Shadow Copying gefällt mir! Allerdings kann ich nicht wie in dem Beispiel "domain.Execute" ausführen, sondern muss eine Instance erzeugen: "domain.Load(AssemblyName.GetAssemblyName(assembly ));" So sieht das aus. Danacht ist die Datei wieder in verwendung und kann nciht gelöscht werden... Übrigens (Ralf) rufe ich über eine eigene AppDomain wie folgt die Assembly auf!

        MfG
        Die Taschenlampe!

        Die perfekte Taschenlampe für Ihr Windows Phone!

        - Die APP steuert die echte Blitz-LED an und versorgt Sie mit 100% Leistung!
        - Zudem zeigt die Live-Kachel den aktuellen Akkustand des Telefons an!


        Hier gehts zu APP!

        Comment


        • #5
          Übrigens (Ralf) rufe ich über eine eigene AppDomain wie folgt die Assembly auf!
          Wo folgt was?

          domain.Load lädt die Assembly auch immer in die aktuelle Domain. Solltest du also nur benutzen wenn dein Code auch gerade in der Domain domain ausgeführt wird.

          Comment


          • #6
            Code:
            private void Window_Loaded(object sender, RoutedEventArgs e)
                    {
                        /* Enable shadow copying */
            
                        // Get the startup path. Both assemblies (Loader and
                        // MyApplication) reside in the same directory:
            
                        string startupPath = System.IO.Path.GetDirectoryName(
                            Assembly.GetExecutingAssembly().Location);
            
            
                        string cachePath = System.IO.Path.Combine(
                            startupPath,
                            "__cache");
                        string configFile = System.IO.Path.Combine(
                            startupPath,
                            "MyApplication.exe.config");
                        string assembly = System.IO.Path.Combine(
                            startupPath,
                            "MyApplication.exe");
            
                        // Create the setup for the new domain:
                        AppDomainSetup setup = new AppDomainSetup();
                        setup.ApplicationName = "MyApplication";
                        setup.ShadowCopyFiles = "true";		// note: it isn't a bool
                        setup.CachePath = cachePath;
                        setup.ConfigurationFile = configFile;
            
                        // Create the application domain. The evidence of this
                        // running assembly is used for the new domain:
                        AppDomain domain = AppDomain.CreateDomain(
                            "MyApplication",
                            AppDomain.CurrentDomain.Evidence,
                            setup);
                        domain.Load(AssemblyName.GetAssemblyName(assembly));
                        // Start MyApplication by executing the assembly:
                        // Das ExecuteAssembly funktioniert!!
                        // domain.ExecuteAssembly(assembly);
            
                        // After the MyApplication has finished clean up:
            
                        AppDomain.Unload(domain);
                        Directory.Delete(cachePath, true);
                    }
            So lade ich Sie. Also in einer eigenen Domain.. oder? :-)

            MfG
            Die Taschenlampe!

            Die perfekte Taschenlampe für Ihr Windows Phone!

            - Die APP steuert die echte Blitz-LED an und versorgt Sie mit 100% Leistung!
            - Zudem zeigt die Live-Kachel den aktuellen Akkustand des Telefons an!


            Hier gehts zu APP!

            Comment


            • #7
              So lade ich Sie. Also in einer eigenen Domain.. oder? :-

              .. und in die aktuelle.

              Zitat Doku



              Diese Methode darf nur zum Laden einer Assembly in die aktuelle Anwendungsdomäne verwendet werden. Diese Methode wird als Annehmlichkeit für Interoperabilitätsaufrufer bereitgestellt, die die statische Assembly.Load-Methode nicht aufrufen können. Um Assemblys in andere Anwendungsdomänen zu laden, verwenden Sie eine Methode wie CreateInstanceAndUnwrap.
              Informationen, die allen Überladungen dieser Methode gemeinsam sind, finden Sie in der Load(AssemblyName)-Methodenüberladung.

              Comment


              • #8
                Danke erstmal, und wie lade ich das dann korrekt. Ich kenn mich nicht mehr aus...

                Hier mal der Code wie dann die Plugins geladen werden:

                Code:
                foreach (Type pluginType in pluginAssembly.GetTypes())
                			{
                				if (pluginType.IsPublic) //Only look at public types
                				{
                					if (!pluginType.IsAbstract)  //Only look at non-abstract types
                					{
                						//Gets a type object of the interface we need the plugins to match
                						Type typeInterface = pluginType.GetInterface("PlugInInterface.IPlugin", true);
                						
                						//Make sure the interface we want to use actually exists
                						if (typeInterface != null)
                						{
                							//Create a new available plugin since the type implements the IPlugin interface
                							Types.AvailablePlugin newPlugin = new Types.AvailablePlugin();
                							
                							//Set the filename where we found it
                							newPlugin.AssemblyPath = FileName;
                                            newPlugin.AssemblyName = pluginAssembly.GetName().Name;
                							
                							//Create a new instance and store the instance in the collection for later use
                							//We could change this later on to not load an instance.. we have 2 options
                							//1- Make one instance, and use it whenever we need it.. it's always there
                							//2- Don't make an instance, and instead make an instance whenever we use it, then close it
                							//For now we'll just make an instance of all the plugins
                							newPlugin.Instance = (IPlugin)Activator.CreateInstance(pluginAssembly.GetType(pluginType.ToString()));
                							
                							//Set the Plugin's host to this class which inherited IPluginHost
                							newPlugin.Instance.Host = this;
                
                							//Call the initialization sub of the plugin
                							newPlugin.Instance.Initialize();
                							
                							//Add the new plugin to our collection here
                							this.colAvailablePlugins.Add(newPlugin);
                							
                							//cleanup a bit
                							newPlugin = null;
                						}	
                						
                						typeInterface = null; //Mr. Clean			
                					}				
                				}			
                			}
                Ganz oben "PluginAssembly" ist die Assembly welche geladen werden soll. Wie lade ich die dann korrekt in eine eigene Domain dass es klappt?
                Danke im Voraus!

                MfG
                Die Taschenlampe!

                Die perfekte Taschenlampe für Ihr Windows Phone!

                - Die APP steuert die echte Blitz-LED an und versorgt Sie mit 100% Leistung!
                - Zudem zeigt die Live-Kachel den aktuellen Akkustand des Telefons an!


                Hier gehts zu APP!

                Comment


                • #9
                  Plugin Laden und AppDomain starten hat jetzt nicht direkt was miteinander zu tun. Wenn du ein Plugin in einer AppDomain ausführen willst brauchst du Code in deiner AppDomain der deinen zuletzt gezeigten Code ausführt.

                  Also

                  1.) Ein Appdomain erzeugen
                  2.) Eine Assembly in der AppDomain erzeugen und starten.
                  3.) Diese in der Appdomain laufenden Assembly deinen obigen Plugin Ladecode ausführen lassen.

                  1. scheinst du schon zu können zu 2. stehen die entscheidende Methoden in meinem Zitat aus der Doku und für 3.tens scheinst du ja ebenfalls schon Code zu haben. Brauchst du nur noch zusammenzusetzen. Und du solltest es wirklich selbst versuchen. Du scheinst hier reines Legoprogramming zu betreiben. Da solltest du zumindest die Gluelogik selbst schreiben um das System auch zu verstehen.

                  Comment


                  • #10
                    Hey Ralf!

                    Ich denke du hattest Recht. Nur so lernt man und ich habs hinbekommen. Allerdings in einer kleinen Anwendung zum testen. In meiner richtigen Anwendung, welche mit WPF-Fenstern unter MVVM arbeitet, gibt es allerdings probleme. Und zwar lade ich die PlugIns lediglich in eine Liste, und lade die Instanz. Bei der Testanwendung beende ich die Plugins ja dann wieder und entlade die AppDomain. Bei der großen Anwendung macht das ja keinen Sinn, da die Plugins gebraucht werden, darum schließe ich sie erst wenn ich ein Update durchführen will, entlade die Liste wo sie sich befinden, entlade danacht die AppDomain. Die Plugins sind dann aber trotzdem Schreibgeschützt. Ich denke ich entlade Sie nicht richtig.
                    Aber ich weiß nicht so recht was ich genau falsch mache. ich denke dass ein einfaches close eben nicht reicht... Hat jemand nen Rat?

                    MfG
                    Die Taschenlampe!

                    Die perfekte Taschenlampe für Ihr Windows Phone!

                    - Die APP steuert die echte Blitz-LED an und versorgt Sie mit 100% Leistung!
                    - Zudem zeigt die Live-Kachel den aktuellen Akkustand des Telefons an!


                    Hier gehts zu APP!

                    Comment


                    • #11
                      Hallo, ich möchte nochmal genauer werden:

                      Innerhalb der MarshalByRefObject-Void, welche die Plugins initialisiert, muss ich ja "irgendwie" die Plugins in eine Liste an die Hauptanwendung übergeben, so dass diese weiß wieviele, und vor allem welche Plugins jetzt da sind. Sobald ich aber irgendetwas nach außen abgebe von der Methode, so landed sie wohl in der Haupt-AppDomain und das Plugin kann nicht mehr gelöscht werden. Wenn ich diese "nur" initialisiere ohne dass meine Anwendung überhaupt weiß das etwas da ist klappts...

                      Wie kann ich das gefundene an die Hauptanwendung übergeben??? (Darunter fallen ein IComman, welches das Plugin erst sichtbar macht, der Name und Anzeigename)

                      MfG
                      Die Taschenlampe!

                      Die perfekte Taschenlampe für Ihr Windows Phone!

                      - Die APP steuert die echte Blitz-LED an und versorgt Sie mit 100% Leistung!
                      - Zudem zeigt die Live-Kachel den aktuellen Akkustand des Telefons an!


                      Hier gehts zu APP!

                      Comment


                      • #12
                        Das sicherste ist wohl sich die Appdomainen wie unabhängige Prozesse vorzustellen. Dann ist klar das wenn man dazwischen kommunizieren will am besten in der IPC Ecke (Remoting, WCF, Named Pipes, Sockets etc.) suchen sollte.

                        Comment


                        • #13
                          Hallo nochmal,

                          aber nochmal ne Frage :-)
                          Soweit läuft das Ding jetz, aber irgendwie überdurchschnittlich kompliziert. Ich meine da es z.B. eine MVVM-Anwendung ist, habe ich einen Messenger, der Nachtrichten zwischen den ViewModels verschickt. Sobald ein Plugin flexibel ge- und entladen werden kann, kann es nicht mehr richtig über diesen Messenger kommunizieren.
                          Das verwalten und übergeben von Daten ist auch äußerst aufwendig.
                          Gibt es soweit keine andere Lösung außer über AppDomains, bzw. ist es doch eigentlich eher besser die Anwendung kurz zu beenden und einem separatem Tool die neuen Plugins installieren zu lassen, oder?

                          Vielen Dank für die Antworten!
                          Die Taschenlampe!

                          Die perfekte Taschenlampe für Ihr Windows Phone!

                          - Die APP steuert die echte Blitz-LED an und versorgt Sie mit 100% Leistung!
                          - Zudem zeigt die Live-Kachel den aktuellen Akkustand des Telefons an!


                          Hier gehts zu APP!

                          Comment


                          • #14
                            Wenn das entladen von Plugins nicht kriegsentscheidend ist würde ich persönlich darauf verzichten. Der Sinn der Appdomainen ist ja die sauberere Isolation untereinander, die freie Entladbarkeit nur ein Nebeneffekt davon. Keines der fertigen UI System ist auf das Vorhandensein verschiedener AppDomainen vorbereitet und du wirst je nachdem was du vorhast gegen das Standardverhalten dieser Systeme kämpfen müssen. Das ganze ist sicherlich möglich, ob sich der Aufwand lohnt kannst aber nur du beurteilen. Ich würde das bezweifeln. Nachdem du dich persönlich tief in die Materie eingearbeitet hast könnten dann Kollegen das System weiterführen ohne ständig was kaputt zu machen wegen nicht offensichtlichem Systemverhalten? Muss du bei Änderungen jedesmal befürchten das die Entladbarkeit nicht mehr funktioniert und hinterherarbeiten?

                            Comment


                            • #15
                              Ja ich lasse das jetzt auch.

                              Denn imemrhin wäre das nur der "Schönheit" wegen. Benötigt wird das so nciht. Denn wenn das Programm ein Update findet, man bestätigt, ist es auch nicht tragisch wenn ein Updatehelfer gestartet wird, die eigentlich Anwendung runterfährt, das Update installiert wird und die Hauptanwendung wieder neu startet. Das ist zum aushalten!

                              Trotdem vielen vielen Dank! Immerhin habe ich so eingies über das arbeiten mit AppDomains und Assemblys gelernt, was ich vorher nicht verstanden/gewusst habe!

                              Schönen Tag noch!
                              Die Taschenlampe!

                              Die perfekte Taschenlampe für Ihr Windows Phone!

                              - Die APP steuert die echte Blitz-LED an und versorgt Sie mit 100% Leistung!
                              - Zudem zeigt die Live-Kachel den aktuellen Akkustand des Telefons an!


                              Hier gehts zu APP!

                              Comment

                              Working...
                              X