Laden...

Updateroutine: Programmdateien selbst überschreiben

Erstellt von deemax vor 16 Jahren Letzter Beitrag vor 16 Jahren 9.605 Views
D
deemax Themenstarter:in
65 Beiträge seit 2004
vor 16 Jahren
Updateroutine: Programmdateien selbst überschreiben

Hallo,

beim Start meiner Winapplikation soll die Exe in einem bestimmten Updateverzeichnis nachschauen ob eine neuere Exe + weitere Programmdateien vorhanden sind. Wenn ja, dann sollen alle Dateien in das Ausführungsverzeichnis kopiert und das Programm soll gestartet werden.
Ich habe an eine zusätzliche Exe-Datei gedacht, die einfach falls neue Dateien vorhanden sind, aufgerufen wird und kopiert. Anschließend wird wieder das Programm gestartet.

Wie kann ich das realisieren oder gibs einfache Möglichkeiten?

3.825 Beiträge seit 2006
vor 16 Jahren

oder gibs einfache Möglichkeiten?

Ja !

Eine Exe-Datei kann sich selbst überschreiben, nur die Exe vorher umbenennen. Auch kann sie sich selbst anhalten und neu starten (nun die neue Version).

Grüße Bernd

Workshop : Datenbanken mit ADO.NET
Xamarin Mobile App : Finderwille Einsatz App
Unternehmenssoftware : Quasar-3

D
deemax Themenstarter:in
65 Beiträge seit 2004
vor 16 Jahren

Hallo Bernd,

ich bin jetzt gerade dabei den Updater zu programmieren. Kann ich auch die dlls zur Exe mitüberschreiben (sind ja eigentlich mit der Exe geladen)?
Wenn ja, kannst du mir einige Tipps geben wie ich das machen kann bzw. die Funktionen nachlesen kann?

D
43 Beiträge seit 2007
vor 16 Jahren

Hi deemax,

Bist du denn schon weitergekommen mit deinem Programm?
ich sitz auch gerade an einem Updater und habe immer das Problem das ich aus C# eine .exe oder .config Datei nicht löschen darf!
ich bekomme immer folgende Fehlermeldung:
Der Zugriff auf den Pfad D:...\Tool.exe wurde verweigert.

mein Code sieht folgendermaßen aus:


string sDirName = Path.GetFullPath(@".\");
try
{
	// Austauschen der Tool.exe
	File.Delete(sDirName + "Tool.exe");
	File.Copy(Properties.Settings.Default.Server_Path + "Tool.exe", sDirName + "Tool.exe", true);
	// Austauschen der Tool.exe.config
	File.Copy(Properties.Settings.Default.Server_Path + "Tool.exe.config", sDirName + "Tool.exe.config", true);
	// Austauschen der Bugs.txt
	File.Copy(Properties.Settings.Default.Server_Path + "Bugs.txt", sDirName + "Bugs.txt", true);

	if (CheckUpdate())
		MessageBox.Show("Das Update war leider nicht erfolgreich", "ERROR", MessageBoxButtons.OK, MessageBoxIcon.Error);
	else
		MessageBox.Show("Sie sind nun wieder auf dem neusten Stand.", "INFO", MessageBoxButtons.OK, MessageBoxIcon.Information);
}
catch (Exception ex)
{
	MessageBox.Show(ex.Message, "ERROR", MessageBoxButtons.OK, MessageBoxIcon.Error);
}

Die Exception tritt schon immer beim löschen von Tool.exe auf.
Wie kann ich denn eine .exe Datei überschreiben?

Gruß
Durin-V

Die drei Erzfeinde eines jeden Programmierers:

  1. Tageslicht
  2. Frischluft
  3. das Gebrüll der Vögel
D
deemax Themenstarter:in
65 Beiträge seit 2004
vor 16 Jahren

Hallo,

nein ich hab noch gar nicht angefangen. Wollte noch auf eine Antwort warten. Du versuchst sie ja direkt zu überschreiben, das funks nicht.

Eine Exe-Datei kann sich selbst überschreiben, nur die Exe vorher umbenennen. Auch kann sie sich selbst anhalten und neu starten (nun die neue Version).

Nur wie ich das technisch machen kann, noch keine Ahung 🙁

1.820 Beiträge seit 2005
vor 16 Jahren

Hallo!

Eine .NET-Exe, die gerade im Speicher läuft, kann nicht überschrieben werden, da Sie zu diesem Zeitpunkt vom .NET-Framework reserviert wurde.

Es gibt drei Möglichkeiten für ein Update:

  1. Ein kleines Start-Programm schreiben, welches die ursprüngliche Exe-Datei in eine neue AppDomain schreibt, am besten noch mit ShadowCopy = true.
  2. Ein externes Update-Programm schreiben (nix großes, nur zum downloaden und installieren). Dieses am besten per Parameter steuern können, dann kann man's auch für andere Programme verwenden. Parameter sind dann z.B. Update-URL und Name des eigenen Programms.
  3. ClickOnce. Allerdings steh' ich damit irgendwie auf Kriegsfuß 8o.

Nobody is perfect. I'm sad, i'm not nobody 🙁

D
43 Beiträge seit 2007
vor 16 Jahren

Ich hab das so schon vorbereitet das ich für das Update extra ein eigenes Programm geschrieben habe. Das Programm Tool.exe läuft nicht im Speicher (Hab das mit dem Task-Manager überprüft) und dennoch kann ich die Datei Tool.exe nicht löschen!
Irgendwas mach ich da wohl noch falsch aber ich weiß nicht was.

Gruß
Durin-V

Die drei Erzfeinde eines jeden Programmierers:

  1. Tageslicht
  2. Frischluft
  3. das Gebrüll der Vögel
D
43 Beiträge seit 2007
vor 16 Jahren

Hi Leute,

ich glaub ich weiß wo der fehler liegt. Wenn ich mit C# irgendetwas aufrufe (ob nun Batch oder direkt File.Delete() ) dann bekomme ich immer den Fehler das der Befehl verweigert wurde.
Ich denke das es an den Rechten von meinem Programm liegt das diese aktionen ausführen will. Nur weiß ich leider nicht wie ich die Rechte meines Programms während der Laufzeit (oder auch schon beim erstellen - Projekteinstellung oder etc.) änder kann damit er das macht.
Ich hab das mit einer Batch Datei geteste bei der ich den selben fehler hatte wenn ich diese mit Process.Start() aufgerufen hab. Wenn ich dei Batch aber mit der ComandoZeile aufgerufen habe dann hat das funktioniert.

Könnt Ihr mir weiterhelfen?

Gruß
Durin-V

Die drei Erzfeinde eines jeden Programmierers:

  1. Tageslicht
  2. Frischluft
  3. das Gebrüll der Vögel
3.825 Beiträge seit 2006
vor 16 Jahren

Wie das geht ?

Dos-Box :


del Tool.ex1
ren Tool.exe Too.ex1
copy update\Tool.exe Tool.exe

Statt del und ren kann man natürlich die C#-Befehle benutzen wie File.Delete. geht auch mit DLL's.

Klar geht das, ich mache das so in meiner Applikation.

Grüße Bernd

Workshop : Datenbanken mit ADO.NET
Xamarin Mobile App : Finderwille Einsatz App
Unternehmenssoftware : Quasar-3

D
43 Beiträge seit 2007
vor 16 Jahren

Hi BerndFfm,

so wie du das geschrieben hast funktioniert es.
Ich das man ein Update Programm schreibt welches denn dann die Benötigten Dateien löscht funktioniert leider nicht. Es kommt immer wieder die Fehlermeldung das ich kein Zugriff darauf habe.

Was nur unschön an dieser Sache ist, ist die Tatsache das das Programm von Hand neu gestartet werden muss. Wenn also einer von euch eine Idee hat dann immer her damit.

Gruß
Durin-V

Die drei Erzfeinde eines jeden Programmierers:

  1. Tageslicht
  2. Frischluft
  3. das Gebrüll der Vögel
D
43 Beiträge seit 2007
vor 16 Jahren

Hi Leute,

ich hab mal meine Update Routine extrahiert und in eine Klassenbibliothek gepackt.
Damit kann man ganz einfach und Übersichtlich die Dateien aktualisieren. 😁
Ihr braucht nur die DLL in der Referenz eintragen und schon kann es losgehen.

Hier noch der Code um die Klasse anzusprechen:


using System;
using System.Collections.Generic;
using System.Text;
using System.IO;
using S_MzH.Update;

namespace UpdateTest
{
    class Program
    {
        static void Main(string[] args)
        {
            // Hier soll die Update.dll getestet werden.
            Update uFilesToUpdate = new Update();
            string sServerPath = @"C:\Update\";
            string sLocalPath = Path.GetFullPath(@".\");

            uFilesToUpdate.AddFile("Datei_1.txt", sServerPath, sLocalPath);
            uFilesToUpdate.AddFile("Datei_2.exe", sServerPath, sLocalPath);

            if (uFilesToUpdate.CheckUpdate())
            {
                // Es liegt ein Update einiger Dateien vor
                uFilesToUpdate.UpdateFiles();
                Console.WriteLine("Das Update war erfolgreich!\r\n");
            }

            Console.WriteLine("Alle Dateien sind auf dem neusten Stand.\r\n");
        }
    }
}

Bitte sagt doch was Ihr davon haltet.

LG
Durin-V

Die drei Erzfeinde eines jeden Programmierers:

  1. Tageslicht
  2. Frischluft
  3. das Gebrüll der Vögel
W
103 Beiträge seit 2007
vor 16 Jahren

Moin moin,
ich benötige auch so eine Updateroutine und habe deshalb deine Klasse mal ausprobiert aber irgendwie ist CheckUpdate immer false bei mir, was prüfst du denn dort genau ab?

Was macht die methode UpdateFiles genau?

Gruß
wettmasta

D
43 Beiträge seit 2007
vor 16 Jahren

Hi wettmasta

die Funktion CheckUpdate überprüft folgendes:
Wenn es sich bei der Datei um eine .exe, .dll oder .msi handelt wird die Version der Datei zuerst überprüft und dann das Alter (also LastWriteTime). Wenn eines von beiden ungleich ist dann kann für diese Datei ein Update ausgeführt werden (rückgabewert = true).
Bei allen anderen Dateien wird immer nur das LastWriteTime ausgewertet.
Wenn du mir mal deinen Codeabschnitt posten könntest dann kann ich mal schauen das ich den Fehler reproduziert bekomme.

LG
Sascha

Die drei Erzfeinde eines jeden Programmierers:

  1. Tageslicht
  2. Frischluft
  3. das Gebrüll der Vögel
W
103 Beiträge seit 2007
vor 16 Jahren

Huhu,
oh jetzt hats funktioniert, das LastWriteTime war wohl net so ganz richtig bei mir.

Aber wie bekommt man es nun hin, das sich die alte anwendung beendet und automatisch die neue .exe geladen wird?

Gruß
Christoph

D
43 Beiträge seit 2007
vor 16 Jahren

Hiho

schön das es jetzt funktioniert. Das automatische beenden und dann neustarten der Applikation steht ganz oben auf meine Liste aber ich hab da leider auch noch keine Lösung gefunden.

Wenn du also eine Idee hast dann immer her damit.

LG
Sascha

Die drei Erzfeinde eines jeden Programmierers:

  1. Tageslicht
  2. Frischluft
  3. das Gebrüll der Vögel
W
103 Beiträge seit 2007
vor 16 Jahren

Gans easy, wir ich gerade gesehen hab....

Application.Restart();

P.S. vielen dank für die Update Klasse

Gruß
Christoph

D
43 Beiträge seit 2007
vor 16 Jahren

Super Danke.

Ich werde heute sobald ich zu hause bin die CheckUpdate Routine um eine kleine Funktion erweitern.

LG
Sascha

Die drei Erzfeinde eines jeden Programmierers:

  1. Tageslicht
  2. Frischluft
  3. das Gebrüll der Vögel
3.825 Beiträge seit 2006
vor 16 Jahren

Was nur unschön an dieser Sache ist, ist die Tatsache das das Programm von Hand neu gestartet werden muss. Wenn also einer von euch eine Idee hat dann immer her damit.

Das Programm kann sich auch selbst neu starten, nachdem es umbenannt ist.

Löschen würde ich die alte exe eh nicht. Wenn die neue nicht funktioniert kann man die alte wieder zurück umbenennen.

string args = "";
foreach (string str in Environment.GetCommandLineArgs()) if (str.ToLower() != "programm.exe") args += str + " ";
System.Diagnostics.Process.Start(Application.StartupPath+@"\programm.exe",args);
this.Close();

Wer's nicht glaub, ich mache das schon lange so.

Grüße Bernd

Workshop : Datenbanken mit ADO.NET
Xamarin Mobile App : Finderwille Einsatz App
Unternehmenssoftware : Quasar-3