Wie starte ich meine C # WinForm-Anwendung neu?

85

Entwickeln einer C # .NET 2.0 WinForm-Anwendung. Die Anwendung muss geschlossen und neu gestartet werden.

Application.Restart();

Das obige Verfahren hat sich als unzuverlässig erwiesen .

Was ist ein besserer Weg, um die Anwendung neu zu starten?

Adam Nofsinger
quelle
3
Ich bin gespannt auf die Notwendigkeit, Ihre App neu zu starten. Ich habe noch nie über dieses Bedürfnis nachgedacht. Wie sind Ihre Umstände?
JeffH
Unser besonderer Umstand - eine Media Player-Anwendung, die einige Bilder und Flash-Inhalte in einer Schleife durchlaufen soll. Sollte tagelang ohne Neustart des Computers ausgeführt werden, und es gibt keine Tastatur / Maus, also keine Benutzerinteraktion. Wenn das Programm abstürzt (nicht behandelte Ausnahme), müssen Sie das Programm neu starten, nicht beenden oder einen Fehler anzeigen. stackoverflow.com/questions/773768/… Sehen Sie, warum das Programm weiterhin Ausnahmen hat, die ich nicht verhindern kann. :(
Adam Nofsinger
1
Am Ende bestand eine viel bessere Lösung für unsere Anwendung darin, eine kleine Watchdog-Anwendung zu entwickeln, die von der Hauptanwendung aus gestartet wird (falls sie noch nicht ausgeführt wird). Der Watchdog überprüft einfach etwa alle 10 Sekunden, ob in der Hauptanwendung noch ein Prozess ausgeführt wird. Wenn dies nicht der Fall ist, wird einer gestartet. Einfach, elegant und viel stabiler als der Versuch, über die Haupt-App neu zu starten.
Adam Nofsinger
1
Ein weiterer Grund für einen Neustart ist, wenn Sie die Sprache ändern oder ein Update heruntergeladen haben.
Andrew Truckle
1
Aber was ist, wenn ... die Watchdog-Anwendung abstürzt?
Metoniem

Antworten:

39

Leider können Sie Process.Start () nicht verwenden, um eine Instanz des aktuell ausgeführten Prozesses zu starten. In den Process.Start () -Dokumenten heißt es: "Wenn der Prozess bereits ausgeführt wird, wird keine zusätzliche Prozessressource gestartet ..."

Diese Technik funktioniert unter dem VS-Debugger einwandfrei (da VS eine Art Magie ausführt, die Process.Start zu der Annahme veranlasst, dass der Prozess noch nicht ausgeführt wird), schlägt jedoch fehl, wenn er nicht unter dem Debugger ausgeführt wird. (Beachten Sie, dass dies möglicherweise betriebssystemspezifisch ist. Ich erinnere mich anscheinend, dass es bei einigen meiner Tests entweder unter XP oder Vista funktioniert hat, aber ich erinnere mich möglicherweise nur daran, es unter dem Debugger ausgeführt zu haben.)

Diese Technik ist genau die, die der letzte Programmierer in dem Projekt verwendet, an dem ich gerade arbeite, und ich habe seit einiger Zeit versucht, eine Problemumgehung dafür zu finden. Bisher habe ich nur eine Lösung gefunden, und es fühlt sich für mich nur schmutzig und klobig an: Starten Sie eine zweite Anwendung, die im Hintergrund darauf wartet, dass die erste Anwendung beendet wird, und startet dann die erste Anwendung neu. Ich bin sicher, es würde funktionieren, aber igitt.

Bearbeiten: Die Verwendung einer zweiten Anwendung funktioniert. Alles was ich in der zweiten App gemacht habe war:

    static void RestartApp(int pid, string applicationName )
    {
        // Wait for the process to terminate
        Process process = null;
        try
        {
            process = Process.GetProcessById(pid);
            process.WaitForExit(1000);
        }
        catch (ArgumentException ex)
        {
            // ArgumentException to indicate that the 
            // process doesn't exist?   LAME!!
        }
        Process.Start(applicationName, "");
    }

(Dies ist ein sehr vereinfachtes Beispiel. Der echte Code enthält viele Informationen zur Überprüfung der geistigen Gesundheit, zur Fehlerbehandlung usw.)

HiredMind
quelle
Ich stimme HiredMind zu und habe kurz nach dem Schreiben der Antwort selbst dieselbe Implementierung des "Watchdog-Programms" durchgeführt. Entschuldigung, hätte hierher zurückkehren und aktualisieren sollen. Ich würde nicht denken, dass es sich zu schrecklich hässlich / eklig / schmutzig anfühlen sollte . Das Watchdog-Programmmuster ist ziemlich weit verbreitet.
Adam Nofsinger
Sie brauchen eigentlich keine zweite Anwendung auf der Festplatte ... Sie könnten ein Skript verwenden und es im laufenden Betrieb mit einem temporären Namen generieren ... Ich denke, dies kann Ihr Schuldgefühl lindern, wenn Sie eine zweite Anwendung zum Neustart haben Ihre eigene ... Oder Sie könnten eine ganze C # -Anwendung "emittieren", sie kompilieren, auf der Festplatte speichern und ausführen (schmutziges, schmutziges Denken).
Loudenvier
Der erste Absatz ist nicht korrekt: Process.StartDie Liste der ausgeführten Betriebssystemprozesse wird nicht angezeigt. Diese Dokumentationsanweisung bezieht sich nur auf diese Objektinstanz der ProcessKlasse. Die ProcessKlasse kann an einen laufenden Prozess angehängt werden, sie kann sich jedoch auch in einem nicht gestarteten Zustand befinden. Meiner Meinung nach ist dies ein Designfehler. Die beste Vorgehensweise, IMO, besteht darin, eine Process Instanz niemals wiederzuverwenden und sofort nach der Erstellung zu starten. Verwenden Sie im Idealfall die statische Process.StartMethode. Dann kommt dieser Dokumentations- und Konstruktionsfehler nie ins Spiel.
usr
Der hier gezeigte Code ist auch wegen unzuverlässig WaitForExit(1000). Das gesamte Warten ist jedoch nicht erforderlich, um einen neuen Prozess zu starten. Möglicherweise möchten Sie zusätzliches Verhalten, aber es ist nicht erforderlich, einen neuen Prozess zu starten.
usr
Ich weiß es jetzt nicht, aber vor neun Jahren (ähm) war das definitiv richtig. :-)
HiredMind
68

Ein viel einfacherer Ansatz, der für mich funktioniert hat, ist:

Application.Restart();
Environment.Exit(0);

Dies behält die Befehlszeilenargumente bei und funktioniert trotz Ereignishandlern, die normalerweise das Schließen der Anwendung verhindern würden.

Der Restart () -Aufruf versucht zu beenden, startet trotzdem eine neue Instanz und kehrt zurück. Der Aufruf von Exit () beendet dann den Prozess, ohne dass Ereignishandler die Möglichkeit haben, ausgeführt zu werden. Es gibt einen sehr kurzen Zeitraum, in dem beide Prozesse ausgeführt werden, was in meinem Fall kein Problem darstellt, aber möglicherweise in anderen Fällen.

Der Exit-Code 0 in Environment.Exit(0);gibt ein sauberes Herunterfahren an. Sie können auch mit 1 beenden, um anzugeben, dass ein Fehler aufgetreten ist.

EMP
quelle
Einfach und doch zuverlässig. Dies sollte die akzeptierte Antwort sein. Ich habe versucht, eine Abmeldefunktion zu implementieren, die alle globalen Variablen leer macht und so aussieht, als ob die Anwendung gerade gestartet wurde. Ich wollte nur das Bedienfeld zum Anmelden anzeigen und alle globalen Variablen, die wichtige Informationen aus der Datenbank enthalten, auf nichts zurücksetzen. Dies machte das Leben viel einfacher. Vielen Dank!
DavidG
System.Windows.Forms.Application.Restart () funktioniert auch für WPF-Anwendungen. Getestet mit Windows 10 OS.
NthDeveloper
55

Wenn Sie sich in der Haupt-App-Form befinden, versuchen Sie es

System.Diagnostics.Process.Start( Application.ExecutablePath); // to start new instance of application
this.Close(); //to turn off current app
Darqer
quelle
7
Es ist ähnlich, aber anders. Application.Exit hat bei mir nicht funktioniert, und this.Close () hat den Job gemacht.
Darqer
1
Mai Enviorment.Exit(0)wird auch den Job machen.
Dwza
1
Enviorment.Exitist ein schmutziger und ziemlich invasiver Exit, da er verhindert, dass Anwendungsbereinigungscode ausgeführt wird. Meistens nicht die richtige Wahl.
usr
16

Ich komme vielleicht zu spät zur Party, aber hier ist meine einfache Lösung, die bei jeder Anwendung, die ich habe, wie ein Zauber wirkt:

        try
        {
            //run the program again and close this one
            Process.Start(Application.StartupPath + "\\blabla.exe"); 
            //or you can use Application.ExecutablePath

            //close this one
            Process.GetCurrentProcess().Kill();
        }
        catch
        { }
SolidSnake
quelle
Funktioniert sehr gut unter Win-7-x64 und Win-XP-x32. Ich sehe nichts über irgendwelche Einschränkungen in den Dokumenten . Dies sollte die akzeptierte Antwort sein.
Bitterblue
@Bitterblue Der Link zu den von Ihnen veröffentlichten Dokumenten lautet "Wenn der Prozess bereits ausgeführt wird, wird keine zusätzliche Prozessressource gestartet." Es ist die 3. Zeile im Abschnitt "Bemerkungen". Ich wünschte, es wäre nicht so, aber es ist so.
HiredMind
@HiredMind Ich denke, wir könnten darüber streiten, was "Einschränkungen" für jeden von uns bedeuten. Der Abschnitt trägt jedoch den Titel "Bemerkungen" und nicht "Einschränkungen". Also kann ich damit leben. Und warum wünschst du dir , es wäre nicht so? Haben Sie damit Probleme gehabt? Weil ich es nicht getan habe. Funktioniert einwandfrei für mich.
Bitterblue
@HiredMind Dies ist nichts Persönliches oder irgendetwas anderes als die Idee, eine zweite App oder ein Skript zu verwenden, um meine C # -App neu zu starten, ist für mich abstoßend. Win7 führt diese Methode im Release-Modus bisher fehlerfrei aus (ich verwende sie, um meine App neu zu starten, wenn der Benutzer die Sprache ändert = nichts Wichtiges). Daher möchte ich den Benutzer lieber anweisen, die App manuell neu zu starten, als Methoden zu verwenden, die ich selbst nicht gutheiße. Ich habe in der Vergangenheit Skripte verwendet und es hat mir überhaupt nicht gefallen.
Bitterblue
@BitterBlue Ich stimme zu, dass die Verwendung einer zweiten App scheiße ist - das habe ich in meiner Antwort gesagt. Aber haben Sie die Single-App-Methode außerhalb des Debuggers ausprobiert? Bei einigen Windows-Versionen funktionierte es nicht, als diese Antwort hinterlassen wurde, und der Release- oder Debug-Modus hatte nichts damit zu tun. Wenn es für Sie funktioniert, großartig! Aber ich wurde von diesem Problem gebissen und was ich bekam, waren Hunderte von wütenden Benutzern.
HiredMind
11

Ich hatte genau das gleiche Problem und musste auch doppelte Instanzen verhindern - ich schlage eine alternative Lösung zu der von HiredMind vorgeschlagenen vor (die gut funktionieren wird).

Ich starte den neuen Prozess mit der processId des alten Prozesses (der den Neustart auslöst) als cmd-Zeilenargument:

// Shut down the current app instance.
Application.Exit();

// Restart the app passing "/restart [processId]" as cmd line args
Process.Start(Application.ExecutablePath, "/restart" + Process.GetCurrentProcess().Id);

Wenn die neue App gestartet wird, analysiere ich zuerst die cm-Zeilenargumente und überprüfe, ob das Neustart-Flag mit einer processId vorhanden ist. Warten Sie dann, bis dieser Prozess beendet ist:

if (_isRestart)
{
   try
   {
      // get old process and wait UP TO 5 secs then give up!
      Process oldProcess = Process.GetProcessById(_restartProcessId);
      oldProcess.WaitForExit(5000);
   }
   catch (Exception ex)
   { 
      // the process did not exist - probably already closed!
      //TODO: --> LOG
   }
}

Ich zeige offensichtlich nicht alle Sicherheitsüberprüfungen, die ich durchgeführt habe usw.

Auch wenn dies nicht ideal ist - ich finde, dass dies eine gültige Alternative ist, sodass Sie keine separate App benötigen, um den Neustart durchzuführen.

JohnIdol
quelle
1
IMHO, dass es eine sauberere Lösung dafür gibt. Ich muss auch eine einzelne Instanz haben und dem Benutzer erlauben, die Anwendung neu zu starten (z. B. wenn sie abstürzt). Ich habe Ihre Lösung fast implementiert, aber mir ist aufgefallen, dass es besser ist, einfach ein anderes Befehlszeilenargument hinzuzufügen, mit dem mehrere Instanzen ausgeführt werden können.
Dennis
mmm, du drehst die Logik um - ich mag es! Das einzige Problem ist, dass, wenn jemand das
cmd-Zeilenargument
Nun, ich hatte das Glück, dass es eine Funktion war, die Benutzer angefordert hatten, also war es WIN-WIN. Ich würde es vorziehen, wenn sie eine /allowMultipleInstancesFlagge "finden" als die ziemlich seltsame /restart.
Dennis
Ja, wenn Sie mehrere Instanzen zulassen, ist dies mit Sicherheit eine bessere Lösung :)
JohnIdol
@ JohnIdol Schön. Ich denke, ich werde mein Flag in "-waitForProcessToExit" oder so ändern, aber ansonsten ist das eine elegantere Lösung. Im Moment habe ich es mit einem ClickOnce-Problem zu tun, eine EXE von einer anderen EXE zu referenzieren, und das würde das lösen.
HiredMind
6

Start / Exit-Methode

// Get the parameters/arguments passed to program if any
string arguments = string.Empty;
string[] args = Environment.GetCommandLineArgs();
for (int i = 1; i < args.Length; i++) // args[0] is always exe path/filename
    arguments += args[i] + " ";

// Restart current application, with same arguments/parameters
Application.Exit();
System.Diagnostics.Process.Start(Application.ExecutablePath, arguments);

Dies scheint besser zu funktionieren als Application.Restart ();

Sie sind sich nicht sicher, wie dies funktioniert, wenn Ihr Programm vor mehreren Instanzen schützt. Ich vermute, Sie sollten besser eine zweite EXE-Datei starten, die pausiert und dann Ihre Hauptanwendung für Sie startet.

Adam Nofsinger
quelle
2
Dies funktioniert möglicherweise nicht, wenn die Anwendung vor mehreren Instanzen geschützt ist.
Majkinetor
Yah, ich habe das Gefühl, Application.Exit () aufzurufen, führt nur dazu, dass eine Nachricht zu einer Warteschlange hinzugefügt wird, die gepumpt werden muss, sodass das zweite Codebit hier in meiner Antwort wahrscheinlich tatsächlich nicht funktioniert.
Adam Nofsinger
Leider funktioniert diese Technik nicht (ich wünschte, es wäre so! Es ist so viel einfacher als meine Lösung). Es funktioniert im Visual Studio-Debugger, jedoch nicht in der Praxis. Siehe meine Antwort für eine klobige Lösung, die außerhalb des Debuggers funktioniert.
HiredMind
HiredMind könnte recht haben. Am Ende habe ich mich für eine Watchdog-Musterlösung entschieden.
Adam Nofsinger
6

Es ist einfach, Sie müssen nur die Application.Restart()Methoden aufrufen , die dazu neigen, Ihre Anwendung zum Neustart aufzurufen. Sie müssen jedoch die lokale Umgebung mit ihren Fehlercodes verlassen:

Application.Restart();
Environment.exit(int errorcode);

Sie können eine Aufzählung von Fehlercodes erstellen, damit Sie diese effektiv verwenden können.
Eine andere Methode besteht darin, die Anwendung zu beenden und den Prozess mit dem ausführbaren Pfad zu starten:

Application.exit();
System.Diagnostics.Process.Start(Application.ExecutablePath);
Sonu
quelle
Hat bei mir gut funktioniert, in meinem Fall ist die Watchdog-App nicht erforderlich.
user685590
3

Versuchen Sie diesen Code:

bool appNotRestarted = true;

Dieser Code muss auch in der Funktion enthalten sein:

if (appNotRestarted == true) {
    appNotRestarted = false;
    Application.Restart();
    Application.ExitThread();
}
Ferhatayhan
quelle
3

Ich habe eine andere Lösung gefunden, vielleicht kann sie auch jeder verwenden.

string batchContent = "/c \"@ECHO OFF & timeout /t 6 > nul & start \"\" \"$[APPPATH]$\" & exit\"";
batchContent = batchContent.Replace("$[APPPATH]$", Application.ExecutablePath);
Process.Start("cmd", batchContent);
Application.Exit();

Code ist vereinfacht, also kümmere dich um Ausnahmen und so;)

br4inp4in
quelle
2

Sie vergessen die Befehlszeilenoptionen / -parameter, die an Ihre aktuell ausgeführte Instanz übergeben wurden. Wenn Sie diese nicht übergeben, führen Sie keinen echten Neustart durch. Stellen Sie die Process.StartInfomit einem Klon der Prozessparameter ein und starten Sie dann.

Wenn Ihr Prozess beispielsweise als gestartet wurde myexe -f -nosplash myfile.txt, wird Ihre Methode nur myexeohne all diese Flags und Parameter ausgeführt.

Erich Mirabal
quelle
2

Ich wollte, dass die neue Anwendung gestartet wird, nachdem die alte heruntergefahren wurde.

Die Verwendung von process.WaitForExit () zum Warten auf das Herunterfahren Ihres eigenen Prozesses macht keinen Sinn. Es wird immer eine Auszeit geben.

Mein Ansatz ist es also, Application.Exit () zu verwenden und dann zu warten, aber die Verarbeitung von Ereignissen für einen bestimmten Zeitraum zuzulassen. Starten Sie dann eine neue Anwendung mit denselben Argumenten wie die alte.

static void restartApp() {
    string commandLineArgs = getCommandLineArgs();
    string exePath = Application.ExecutablePath;
    try {
        Application.Exit();
        wait_allowingEvents( 1000 );
    } catch( ArgumentException ex ) {
        throw;
    }
    Process.Start( exePath, commandLineArgs );
}

static string getCommandLineArgs() {
    Queue<string> args = new Queue<string>( Environment.GetCommandLineArgs() );
    args.Dequeue(); // args[0] is always exe path/filename
    return string.Join( " ", args.ToArray() );
}

static void wait_allowingEvents( int durationMS ) {
    DateTime start = DateTime.Now;
    do {
        Application.DoEvents();
    } while( start.Subtract( DateTime.Now ).TotalMilliseconds > durationMS );
}
Mike Coxeter
quelle
2

Sie können auch Restarter verwenden .

Restarter ist eine Anwendung, die abgestürzte oder blockierte Programme und Anwendungen automatisch überwacht und neu startet. Es wurde ursprünglich zum Überwachen und Neustarten von Spieleservern entwickelt, erledigt jedoch alle Aufgaben für jedes konsolen- oder formularbasierte Programm oder jede Anwendung

Daniel Rose
quelle
1
Der bereitgestellte Link funktioniert nicht mehr, aber ich denke, dies ist dieselbe Anwendung auf CNET: download.cnet.com/Restarter/3000-2094_4-75810552.html
Surfbutler
2
public static void appReloader()
    {
        //Start a new instance of the current program
        Process.Start(Application.ExecutablePath);

        //close the current application process
        Process.GetCurrentProcess().Kill();
    }

Application.ExecutablePath gibt Ihren .exe-Dateipfad für Anwendungen zurück. Befolgen Sie die Reihenfolge der Aufrufe. Möglicherweise möchten Sie es in eine try-catch-Klausel einfügen.

Olfredos6
quelle
1

Wie wäre es, wenn Sie eine Bat-Datei erstellen, die Batch-Datei vor dem Schließen ausführen und dann die aktuelle Instanz schließen.

Die Batch-Datei führt Folgendes aus:

  1. Warten Sie in einer Schleife, um zu überprüfen, ob der Prozess beendet wurde.
  2. Starten Sie den Prozess.
AZ.
quelle
Welches ist die Watchdog-Anwendung eines armen Mannes, die ich oben etwas detaillierter beschreibe. Der Hauptvorteil einer echten Watchdog-Anwendung besteht darin, dass sie sogar funktioniert, wenn die ursprüngliche App stirbt, ohne dass etwas abgespalten werden kann.
Adam Nofsinger
@AdamNofsinger sehe ich jetzt. Ich habe diesen Kommentar verpasst. Möglicherweise möchten Sie Ihren Beitrag mit der von Ihnen verwendeten Lösung bearbeiten.
AZ.
1

Hier sind meine 2 Cent:

Die Sequenz Neue Instanz starten-> Aktuelle Instanz schließen sollte auch für Anwendungen funktionieren, bei denen nicht mehrere Kopien gleichzeitig ausgeführt werden können. In diesem Fall wird der neuen Instanz möglicherweise ein Befehlszeilenargument übergeben, das angibt, dass ein Neustart ausgeführt wird Daher ist es nicht erforderlich, nach anderen laufenden Instanzen zu suchen. Warten Sie, bis die erste Instanz tatsächlich abgeschlossen ist, und implementieren Sie sie, wenn es unbedingt erforderlich ist, dass keine zwei Instanzen parallel ausgeführt werden.

Felix Prangishvili
quelle
1

Ich befürchte, dass ein Neustart der gesamten Anwendung mit Process Ihr Problem falsch angeht.

Eine einfachere Möglichkeit besteht darin, die Datei Program.cs so zu ändern, dass sie neu gestartet wird:

    static bool restart = true; // A variable that is accessible from program
    static int restartCount = 0; // Count the number of restarts
    static int maxRestarts = 3;  // Maximum restarts before quitting the program

    /// <summary>
    /// The main entry point for the application.
    /// </summary>
    [STAThread]
    static void Main()
    {
        Application.EnableVisualStyles();
        Application.SetCompatibleTextRenderingDefault(false);

        while (restart && restartCount < maxRestarts)
        {
           restart = false; // if you like.. the program can set it to true again
           restartCount++;  // mark another restart,
                            // if you want to limit the number of restarts
                            // this is useful if your program is crashing on 
                            // startup and cannot close normally as it will avoid
                            // a potential infinite loop

           try {
              Application.Run(new YourMainForm());
           }
           catch {  // Application has crashed
              restart = true;
           }
        }
    }
Andrew
quelle
1
Es ist erwähnenswert, dass Sie mit dieser Lösung die Anwendung X-mal neu starten und anschließend die Anwendung beenden können, um eine Endlosschleife zu vermeiden.
RooiWillie
Danke @RooiWillie Ich habe einen Zähler hinzugefügt, um genau das zu tun, falls das Programm nicht normal beendet werden kann.
Andrew
0

Ich hatte ein ähnliches Problem, aber mein Problem hing mit einem nicht verwaltbaren Speicherverlust zusammen, den ich in einer App, die rund um die Uhr ausgeführt werden muss, nicht finden konnte. Mit dem Kunden stimmte ich zu, dass die sichere Zeit für den Neustart der App 03:00 Uhr war, wenn der Speicherverbrauch über dem definierten Wert lag.

Ich habe es versucht Application.Restart, aber da es einen Mechanismus zu verwenden scheint, der eine neue Instanz startet, während sie bereits ausgeführt wird, habe ich mich für ein anderes Schema entschieden. Ich habe den Trick verwendet, den Dateisystem-Handles beibehalten, bis der Prozess, der sie erstellt hat, stirbt. Also habe ich aus der Anwendung die Datei auf die Festplatte gelegt und nichtDispose() das Handle nicht ausgeführt. Ich habe die Datei verwendet, um die ausführbare Datei und das Startverzeichnis von "mir" zu senden (um die Flexibilität zu erhöhen).

Code:

_restartInProgress = true;
string dropFilename = Path.Combine(Application.StartupPath, "restart.dat");
StreamWriter sw = new StreamWriter(new FileStream(dropFilename, FileMode.Create, FileAccess.ReadWrite, FileShare.ReadWrite));
sw.WriteLine(Application.ExecutablePath);
sw.WriteLine(Application.StartupPath);
sw.Flush();
Process.Start(new ProcessStartInfo
{
    FileName = Path.Combine(Application.StartupPath, "VideoPhill.Restarter.exe"),
    WorkingDirectory = Application.StartupPath,
    Arguments = string.Format("\"{0}\"", dropFilename)
});
Close();

Close()Am Ende würde das Herunterfahren der App eingeleitet, und das StreamWriterhier verwendete Dateihandle würde offen gehalten, bis der Prozess wirklich stirbt. Dann...

Restarter.exe wird aktiv. Es wird versucht, die Datei im exklusiven Modus zu lesen, um zu verhindern, dass sie Zugriff erhält, bis die Haupt-App nicht tot ist. Anschließend wird die Haupt-App gestartet, die Datei gelöscht und existiert. Einfacher geht es wohl nicht:

static void Main(string[] args)
{
    string filename = args[0];
    DateTime start = DateTime.Now;
    bool done = false;
    while ((DateTime.Now - start).TotalSeconds < 30 && !done)
    {
        try
        {
            StreamReader sr = new StreamReader(new FileStream(filename, FileMode.Open, FileAccess.ReadWrite, FileShare.ReadWrite));
            string[] runData = new string[2];
            runData[0] = sr.ReadLine();
            runData[1] = sr.ReadLine();
            Thread.Sleep(1000);
            Process.Start(new ProcessStartInfo { FileName = runData[0], WorkingDirectory = runData[1] });
            sr.Dispose();
            File.Delete(filename);
            done = true;
        }
        catch (Exception ex)
        {
            Console.WriteLine(ex.Message);
        }
        Thread.Sleep(1000);
    }
}
Daniel Mošmondor
quelle
0

Ich benutze das Folgende und es macht genau das, wonach Sie suchen:

ApplicationDeployment ad = ApplicationDeployment.CurrentDeployment;
UpdateCheckInfo info = null;
info = ad.CheckForDetailedUpdate();
if (info.IsUpdateRequired)
{
    ad.UpdateAsync(); // I like the update dialog
    MessageBox.Show("Application was upgraded and will now restart.");
    Environment.Exit(0);
}
TomServo
quelle
0

Für die Verwendung als Abmeldung müssen Sie alle Apps aus dem Ram-Cache beenden. Schließen Sie daher zuerst die Anwendung und führen Sie sie erneut aus

// beim Klicken auf die Schaltfläche Abmelden

foreach(Form frm in Application.OpenForms.Cast<Form>().ToList())
        {
            frm.Close();
        }
System.Diagnostics.Process.Start(Application.ExecutablePath);
Ahmed Aboelez
quelle
0

Das Problem bei der Verwendung von Application.Restart () besteht darin, dass ein neuer Prozess gestartet wird, der "alte" jedoch noch vorhanden ist. Aus diesem Grund habe ich beschlossen, den alten Prozess mit dem folgenden Codeausschnitt zu beenden:

            if(Condition){
            Application.Restart();
            Process.GetCurrentProcess().Kill();
            }

Und es funktioniert richtig gut. In meinem Fall verwenden MATLAB und eine C # -Anwendung dieselbe SQLite-Datenbank. Wenn MATLAB die Datenbank verwendet, sollte die Form-App erneut gestartet werden (+ Countdown), bis MATLAB sein Besetztbit in der Datenbank zurückgesetzt hat. (Nur zur Information)

Ricardo Fercher
quelle
0

Sie können Ihren Code in eine Funktion einschließen, und wenn ein Neustart erforderlich ist, können Sie die Funktion einfach aufrufen.

Petr Mach
quelle