2009-06-17 13 views
6

Ich verwende Microsoft Visual Studio 2008 mit einer Windows-Ziel-Bereitstellung. Wie würde ich eine Datei "selbst aktualisieren" machen? Ich habe bereits den "Übertragen über ein Netzwerk" -Teil runter, aber wie mache ich eine ausführbare Datei über sich selbst schreiben?Wie mache ich eine Datei Selbstaktualisierung (Native C++)

Grundsätzlich möchte ich einen Auto-Updater für ein Verzeichnis schreiben, das auch den Auto-Updater enthält, und der Updater muss ALLES im Verzeichnis aktualisieren.

Vielleicht funktionieren die Änderungen an der Datei, bis die Datei gesperrt wird. Wenn ich das tun würde, würde ich wahrscheinlich mit einem Hot-Patch weitermachen.

+0

Mögliche Dupe: http://stackoverflow.com/questions/250175/writing-my-own-auto-updater – crashmstr

+1

kein Betrogene, dies ist speziell NATIVE C++. –

Antwort

5

Schreiben Sie eine neue ausführbare Datei und löschen oder speichern Sie eine Kopie der alten - Sie könnten eine Diff über das Netzwerk senden und haben ein drittes Programm, den Update-Monitor oder was auch immer, um es anzuwenden. Es wäre nur ein kleines Skript, das von der Remote-App aus gestartet werden könnte, wenn ein Update verfügbar ist. Der Updater könnte sich selbst in $ UPDATER_OLD_VERSION oder was auch immer umbenennen, eine aktualisierte Kopie von sich selbst mit dem entsprechenden Namen schreiben und dann, wenn der neue Updater ausgeführt wird, prüfen, ob es eine Datei namens $ UPDATER_OLD_VERSION im App-Verzeichnis gibt und löschen. Alle anderen Dateien könnten einfach aktualisiert/überschrieben werden.

+0

Nein.Diese Lösung ist zu chaotisch für mich. Ich würde lieber keine "Temp-Daten" herumschweben lassen. Was ist, wenn der Computer in der Mitte abstürzt? –

+3

@wowus - Viel besser, dass es temporäre Daten abstürzt als das Überschreiben der eigentlichen exe. Außerdem ist das Problem einfach: Schreiben Sie in eine temporäre Datei und rufen Sie dann MoveFile auf, um es an den endgültigen Speicherort zu setzen. Auf demselben Volume ist MoveFile atomar, sodass ein Absturz keinen inkonsistenten Zustand verursacht. – Michael

+0

SoloBolds Vorschlag ist, wie so etwas im Allgemeinen gemacht wird. Die Appliation, die Sie aktualisieren, kann sich nicht selbst aktualisieren. Wie Sie sagen, was passiert, wenn der Computer in der Mitte abstürzt? –

2

Ich mache dies mit einer InnoSetup setup.exe, die im Hintergrund gestartet wird und meine App herunterfährt, bevor es beginnt, die neuen Dateien zu installieren. Ich musste benutzerdefinierte Pascal [Code] Abschnitte hinzufügen, um sicherzustellen, dass alles heruntergefahren wird, aber es macht den Job.

+0

Kurz, wenn ich einen Gerätetreiber schreibe oder das Betriebssystem hacke, denke ich, dass ein solcher Plan der einzige Weg ist, dies zu tun. Wenn Sie eine ausführbare Datei unter Windows ausführen, hält das Betriebssystem sie schreibgeschützt geöffnet. –

3

Sie können eine App in der Regel nicht ändern, während sie ausgeführt wird. Sie müssen das ursprüngliche Programm schließen und von einem anderen Ort ändern.

2

Sie können eine Datei während der Ausführung nicht überschreiben, aber Sie können sie umbenennen. In meinem Updater benenne ich die existierende exe in etwas Sinnvolles (oldname_dateandtime) um und schreibe dann die neue Kopie hinein. Dann schalte unser System automatisch herunter und starte es von einem Dienst neu. Wenn die App startet, wird die neue Version ausgeführt.

+0

Ich mache das gleiche und bereinige alte Versionen beim Start. –

+0

Wir lassen die alten herum, damit unsere Außendiensttechniker im Falle eines Problems zurückkehren können. Natürlich haben wir den Luxus von Außendiensttechnikern :-). Alte Versionen werden beim nächsten Upgrade-Tick gelöscht. –

0

Wenn ich einen Updater gemacht habe, sollte ich das Programm mehrere trennen. Der Hauptgrund war genau das, was Sie tun möchten. Einfach sagen, B aktualisiert Zielanwendung plus A und A aktualisiert B. Ich habe versucht, einen anderen Weg zu finden, aber was ich getan habe, wurde extra kleine und einfache Updater gemacht. :(

0

Ich glaube, Sie sprechen über Dateiversionen und updaters. Wie Sie sagten, Sie autoupdater.So benötigen Sie einen Dienst erstellen müssen, die Ihr Verzeichnis installieren überwacht und vergleicht die Dateiversion auf der Festplatte mit dem Server.

Sobald Mismatch geschieht können Sie neueste Daten vom Server fragen. Wenn die Dateien im Einsatz zu ersetzen gehen Sie sie zum Löschen/Deregistrierung bei der nächsten Neustart markieren müssen, und Sie können diese mithilfe von Registrierungs erwähnen.

Sie können kopieren Alle Dateien im Cache und später während des Neustarts kopieren sie in das Installationsverzeichnis

4

So habe ich es kürzlich gemacht. Es gibt eine kurze Überschneidung des laufenden Programms und der laufenden neuen Programmierung. Es verwendet den Trick, dass Sie die aktuelle ausführbare Datei umbenennen und die neue Datei an Ort und Stelle bringen können, bevor Sie die alte herunterfahren. Dies ist nicht zu 100% fehlersicher, aber die einzige Möglichkeit, die Ihre Anwendung "brick" machen könnte, ist, wenn CopyFile fehlschlägt.

#include <windows.h> 
#include <iostream> 
#include <fstream> 

void UpgradeService::UpgradeSelf() { 

    std::string temp = root   + "\\myprogram_tmp.exe"; 
    remove(temp.c_str()); // ignore return code 

    std::string src = upgradeFolder + "\\myprogram.exe"; 
    std::string dst = root   + "\\myprogram.exe"; 


    rename(dst.c_str(),temp.c_str()); 
    CopyFile(src.c_str(),dst.c_str(),false); 
    static char buffer[512]; 
    strcpy(buffer,dst.c_str()); 

    /* CreateProcess API initialization */ 
    STARTUPINFO siStartupInfo; 
    PROCESS_INFORMATION piProcessInfo; 
    memset(&siStartupInfo, 0, sizeof(siStartupInfo)); 
    memset(&piProcessInfo, 0, sizeof(piProcessInfo)); 
    siStartupInfo.cb = sizeof(siStartupInfo); 

    ::CreateProcess(buffer, // application name/path 
    NULL, // command line (optional) 
    NULL, // no process attributes (default) 
    NULL, // default security attributes 
    false, 
    CREATE_DEFAULT_ERROR_MODE | CREATE_NEW_CONSOLE, 
    NULL, // default env 
    NULL, // default working dir 
    &siStartupInfo, 
    &piProcessInfo); 


    ::TerminateProcess(GetCurrentProcess(),0); 
    ::ExitProcess(0); // exit this process 

    // this does not return. 
} 
Verwandte Themen