Frage

Ich möchte meine Exe vom Remote-Server aktualisieren.Wenn Sie also auf meine wpf-Anwendung klicken, wird die Remote- und auch eine Remote-TXT-Datei heruntergeladen und die aktuellen Dateien in demselben Ordner ersetzt, in dem exe ausgeführt wird.Es wird also die aktuelle txt- und exe-Datei überschreiben, während meine exe ausgeführt wird.Wie kann ich das erreichen?

Remote-Host ist eine URL wie www.mydomain.com/MyAPP.exe

wpf-Anwendung, c # 4.0

War es hilfreich?

Lösung

Wir haben dieses Problem behoben, indem wir eine Shell-Exe erstellt haben, die ursprünglich auf den Client-Computern installiert und bereitgestellt wurde.

Das "echte" ausführbare Programm wird in einem Unterverzeichnis dieser ersten App gespeichert.Wenn die Shell-App gestartet wird, nachdem sie Updates für die reale App heruntergeladen und installiert hat, wird die ausführbare Datei der realen App in einer separaten AppDomain gestartet.

Hier ist der Kern der "echten" App, die aus der Shell-App heraus gestartet wird:

        System.AppDomainSetup oSetup = new System.AppDomainSetup();
        string sApplicationFile = null;

        // Use this to ensure that if the application is running when the user performs the update, that we don't run into file locking issues.
        oSetup.ShadowCopyFiles = "true";
        oSetup.ApplicationName = sAppName;

        // Generate the name of the DLL we are going to launch
        sApplicationFile = System.IO.Path.Combine(sApplicationDirectory, sAppName + ".exe");

        oSetup.ApplicationBase = sApplicationDirectory;
        oSetup.ConfigurationFile = sApplicationFile + ".config";
        oSetup.LoaderOptimization = LoaderOptimization.MultiDomain;

        // Launch the application
        System.AppDomain oAppDomain = AppDomain.CreateDomain(sAppName, AppDomain.CurrentDomain.Evidence, oSetup);
        oAppDomain.SetData("App", sAppName);
        oAppDomain.SetData("User", sUserName);
        oAppDomain.SetData("Pwd", sUserPassword);

        oAppDomain.ExecuteAssembly(sApplicationFile);

        // When the launched application closes, close this application as well
        Application.Exit();

Beachten Sie, dass in unserer Version die Shell-App den Benutzernamen und das Kennwort vom Benutzer sammelt, um korrekt auf die Update-Website zuzugreifen.Diese Daten werden dann über die SetData-Methode in der AppDomain an die "echte" App übergeben.

Andere Tipps

Die Lösung hängt von Ihrem speziellen Fall ab. Es gibt jedoch keine geradlinige Lösung, da Sie keine Baugruppen aktualisieren können, während sie in den Speicher geladen und verwendet werden. Ich kann 2 Lösungen vorschlagen: mit Schatten kopieren und mit einer Art Helfer ausführbar. Ich habe beide verwendet.

Schattenkopieren.

Die offensichtliche Möglichkeit besteht darin, Ihre Hauptausführung, um den Schatten kopiert zu werden, ersetzen, während Ihre App läuft, und starten Sie die App erneut. Sie können Ihre Standard-App-Domäne nicht nicht erstellen, um den Schatten kopiert zu sein, nur sekundäre App-Domänen können sein. Sie können jedoch immer noch Ihren gesamten Code in eine andere Versammlung (sagen, mainapplib.dll) verschieben und Ihre Haupt-App-Datei ausführbar (mainapp.exe) neu schreiben, damit sie nur "Loader-Code" enthält. Dieser Loader-Code muss eine andere App-Domäne erstellen, einstellen Sie es, um den Schatten kopiert zu werden, und führen Sie Ihre Programmlogik in der sekundären App-Domäne aus. Achten Sie nicht, um keine direkten Referenzen von Ihrer Haupt-App-Domäne in MainAppPlib.dll zu haben, da diese Baugruppe in Ihre Haupt-App-Domäne geladen wird, die nicht schattenkopiert ist und die Assembly-Datei gesperrt wird. In den meisten Fällen können Sie mit appdomain.executeasembly () Methoden.

helfer ausführbar

Die Idee ist, eine Art von Update-Finisher zu verwenden. Ihre Haupt-App bleibt unverändert, Sie fügen nur ein wenig Code hinzu, so dass Ihre App das Update herunterladen, es in den temporären Ordner einfügen, und dann startet Ihre Haupt-App-Update-Finisher ( in einem separaten Prozess ) und beendet. Update-Finisher wartet, bis Ihre App schließt, und kopiert neue Dateien aus temporärem Ordner in Ihren App-Ordner in Ihren App-Ordner, der alle Dateien ersetzt. Update-Finisher kann die eigene ausführbare Datei nicht ersetzen, kann jedoch von der Hauptanwendung erfolgen, bevor er den Update-Finisher beginnt. Nach dem Kopieren von Dateien Update läuft Finisher Ihre Anwendung.

p.s. Persönlich bevorzuge ich die frühere Lösung, da es eine Art Voodoo-Magie mit App-Domains, Reflexion, Anordnungen handelt, E.T.C. Und es kann zur Verwendung von Plugins entwickelt werden, wenn Sie benötigen (z. B. über MEF Framework ). Letzteres ist jedoch einfacher zu verstehen, insbesondere wenn Sie noch nie mit App-Domains und manuellen Baugruppen geladen haben, ist es ziemlich unkompliziert.

Sie könnten wahrscheinlich ClickOnce verwenden (basierend auf Ihrem obigen Kommentar)Sie wären bereit, wenn eine andere Baugruppe die Exe erhält ... wie auf dem anderen Poster erwähnt, können Sie eine laufende Baugruppe nicht ersetzen.Sie können es so konfigurieren, dass es zu verschiedenen Zeiten (z. B. beim Start) nach neuen Versionen sucht und diese automatisch herunterlädt.Es ist eine sehr robuste Lösung, und Sie können viel mit den Bereitstellungsbaugruppen tun.

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