Come si riavvia la mia applicazione WinForm C #?


86

Sviluppo di un'applicazione WinForm C # .NET 2.0. È necessario che l'applicazione si chiuda e si riavvii.

Application.Restart();

Il metodo sopra si è dimostrato inaffidabile .

Qual è un modo migliore per riavviare l'applicazione?


3
Sono curioso della necessità di riavviare la tua app. Non avevo mai pensato a quel bisogno prima. Quali sono le tue circostanze?
JeffH

La nostra circostanza particolare: un'applicazione di lettore multimediale che dovrebbe scorrere alcune immagini e il contenuto flash in un ciclo. Dovrebbe funzionare per giorni e giorni senza un riavvio della macchina e non sono presenti tastiera / mouse, quindi nessuna interazione da parte dell'utente. Se il programma si blocca (eccezione non gestita), è necessario riavviare il programma, non uscire o visualizzare un errore. stackoverflow.com/questions/773768/… Vedi quello per cui il programma continua ad avere eccezioni che non posso prevenire. :(
Adam Nofsinger,

1
Alla fine, una soluzione molto migliore per la nostra applicazione è stata quella di sviluppare una piccola applicazione Watchdog che viene avviata (se non è già in esecuzione) dall'applicazione principale. Il watchdog controlla semplicemente ogni 10 secondi circa per vedere se l'applicazione principale ha ancora un processo in esecuzione e, in caso contrario, ne avvia uno. Semplice, elegante e molto più robusto del tentativo di riavviare dall'app principale.
Adam Nofsinger

2
Un altro motivo per il riavvio è quando cambi la lingua o hai scaricato un aggiornamento.
Andrew Truckle

1
Ma cosa succede se ... L'applicazione watchdog si blocca?
Metoniem

Risposte:


40

Sfortunatamente non puoi usare Process.Start () per avviare un'istanza del processo attualmente in esecuzione. Secondo la documentazione di Process.Start (): "Se il processo è già in esecuzione, non viene avviata alcuna risorsa di processo aggiuntiva ..."

Questa tecnica funzionerà bene con il debugger VS (perché VS fa una sorta di magia che fa sì che Process.Start pensi che il processo non sia già in esecuzione), ma fallirà se non viene eseguito nel debugger. (Nota che questo potrebbe essere specifico del sistema operativo: mi sembra di ricordare che in alcuni dei miei test ha funzionato su XP o Vista, ma potrei semplicemente ricordarmi di eseguirlo sotto il debugger.)

Questa tecnica è esattamente quella usata dall'ultimo programmatore del progetto su cui sto attualmente lavorando, e ho cercato di trovare una soluzione per questo per un po 'di tempo. Finora, ho trovato solo una soluzione, e mi sembra solo sporca e disordinata: avvia una seconda applicazione, che attende in background la fine della prima applicazione, quindi riavvia la prima applicazione. Sono sicuro che funzionerebbe, ma, bleah.

Modifica: funziona una seconda applicazione. Tutto quello che ho fatto nella seconda app è stato:

    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, "");
    }

(Questo è un esempio molto semplificato. Il codice reale ha molti controlli di integrità, gestione degli errori, ecc.)


Sono d'accordo con HiredMind e in realtà sono andato con la stessa implementazione del "programma Watchdog" poco dopo aver scritto la risposta. Spiacenti, sarebbe dovuto tornare qui e aggiornare Non penserei che dovrebbe sembrare troppo orribilmente brutto / schifoso / sporco. Il pattern del programma Watchdog è ampiamente utilizzato.
Adam Nofsinger,

In realtà non hai bisogno di una seconda applicazione su disco ... potresti usare uno script e generarlo al volo con un nome temporaneo ... Penso che questo possa alleviare il tuo senso di colpa avere una seconda applicazione per il gusto di riavviare il tuo ... Oppure potresti "emettere" un'intera applicazione C #, compilarla, salvarla su disco ed eseguirla (sporco, pensiero sporco) ..
Loudenvier

Il primo paragrafo non è corretto: Process.Startnon guarda l'elenco dei processi del sistema operativo in esecuzione. Questa dichiarazione di documentazione parla solo di quell'istanza dell'oggetto della Processclasse. La Processclasse può essere collegata a un processo in esecuzione, ma può anche trovarsi in uno stato non avviato. Secondo me questo è un errore di progettazione. La migliore pratica, IMO, è di non riutilizzare mai Process un'istanza e di avviarla immediatamente dopo la creazione. Idealmente, usa il Process.Startmetodo statico . Quindi, questa documentazione e questo difetto di progettazione non entrano mai in gioco.
usr

Anche il codice mostrato qui è inaffidabile a causa di WaitForExit(1000). Ma l'intera attesa non è necessaria per iniziare un nuovo processo. Potrebbe essere un comportamento aggiuntivo che desideri, ma non è necessario avviare un nuovo processo.
usr

Non lo so adesso, ma nove anni fa (ehm) era decisamente corretto. :-)
HiredMind

74

Un approccio molto più semplice che ha funzionato per me è:

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

Ciò preserva gli argomenti della riga di comando e funziona nonostante i gestori di eventi che normalmente impedirebbero la chiusura dell'applicazione.

La chiamata Restart () tenta di uscire, avvia comunque una nuova istanza e ritorna. La chiamata Exit () termina quindi il processo senza dare la possibilità a nessun gestore di eventi di essere eseguito. C'è un periodo molto breve in cui entrambi i processi sono in esecuzione, il che non è un problema nel mio caso, ma forse in altri casi.

Il codice di uscita 0 in Environment.Exit(0);specifica un arresto pulito. È inoltre possibile uscire con 1 per specificare che si è verificato un errore.


Semplice, ma affidabile. Questa dovrebbe essere la risposta accettata. Stavo cercando di implementare una funzione di disconnessione che svuotare tutte le variabili globali e apparire come se l'applicazione fosse appena stata avviata. Volevo solo mostrare il pannello per l'accesso e resettare tutte le variabili globali che contengono informazioni importanti dal DB a niente. Questo ha reso la vita molto più semplice. Grazie!
DavidG

System.Windows.Forms.Application.Restart () funziona anche per le applicazioni WPF. Testato con sistema operativo Windows 10.
NthDeveloper

Whaaaat ?! Stai scherzando ... vero? C # <3. Tieni presente che questo per impostazione predefinita non genererà OnClose()eventi del modulo e simili.
F8ER

56

Se ti trovi nel modulo dell'app principale, prova a utilizzare

System.Diagnostics.Process.Start( Application.ExecutablePath); // to start new instance of application
this.Close(); //to turn off current app

7
È simile, ma diverso. Application.Exit non ha funzionato da me, e this.Close () ha fatto il lavoro.
Darqer

1
Può Enviorment.Exit(0)anche fare il lavoro.
Dwza

2
Enviorment.Exitè un'uscita sporca e piuttosto invasiva perché impedisce l'esecuzione del codice di pulizia dell'applicazione. La maggior parte delle volte non è la scelta giusta.
usr

16

Potrei essere in ritardo alla festa, ma ecco la mia semplice soluzione e funziona a meraviglia con ogni applicazione che ho:

        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
        { }

Funziona molto bene su Win-7-x64 e Win-XP-x32. Non vedo nulla su eventuali vincoli nei documenti . Questa dovrebbe essere la risposta accettata.
Bitterblue

@Bitterblue Il collegamento ai documenti che hai pubblicato afferma "Se il processo è già in esecuzione, non viene avviata alcuna risorsa di processo aggiuntiva." È la terza riga nella sezione dei commenti. Vorrei che non fosse così, ma lo è.
HiredMind

@HiredMind Immagino che potremmo discutere su cosa significhi "vincoli" per ciascuno di noi. Ma la sezione è intitolata "Osservazioni" non "Vincoli". Quindi posso conviverci. E perché vorresti che non fosse così? Hai avuto problemi con questo? Perché non l'ho fatto. Funziona perfettamente per me.
Bitterblue

@HiredMind Non è niente di personale o altro, ma l'idea di utilizzare una seconda app o uno script solo per riavviare la mia app C # mi repellente. Win7 esegue questo metodo in modalità di rilascio in modo impeccabile finora (lo uso per riavviare la mia app quando l'utente cambia lingua = niente di importante). Quindi preferirei dire all'utente di riavviare l'app manualmente piuttosto che utilizzare metodi che non approvo io stesso. Ho usato script in passato e non mi è piaciuto affatto.
Bitterblue

@BitterBlue Sono d'accordo che l'utilizzo di una seconda app fa schifo - l'ho detto nella mia risposta. Ma hai provato il metodo della singola app al di fuori del debugger? Non ha funzionato su alcune versioni di Windows quando ha lasciato questa risposta e la modalità di rilascio o debug non ha nulla a che fare con esso. Se per te funziona, bene! Ma sono stato morso da questo problema e quello che ho ottenuto sono stati centinaia di utenti arrabbiati.
HiredMind

13

Avevo lo stesso identico problema e anch'io avevo la necessità di evitare casi duplicati: propongo una soluzione alternativa a quella proposta da HiredMind (che funzionerà bene).

Quello che sto facendo è avviare il nuovo processo con processId del vecchio processo (quello che attiva il riavvio) come argomento della riga cmd:

// 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);

Quindi, quando la nuova app viene avviata, prima analizzo gli argomenti della riga cm e controllo se il flag di riavvio è presente con un processId, quindi aspetto che il processo esca:

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
   }
}

Ovviamente non sto mostrando tutti i controlli di sicurezza che ho in atto ecc.

Anche se non è l'ideale, trovo che sia una valida alternativa in modo da non dover disporre di un'app separata solo per gestire il riavvio.


1
IMHO che c'è una soluzione più ordinata a questo. Ho anche un requisito per avere una singola istanza e consentire all'utente di riavviare l'applicazione (ad esempio quando si blocca). Ho quasi implementato la tua soluzione, tuttavia mi è venuto in mente che sarebbe stato meglio aggiungere semplicemente un diverso argomento della riga di comando che consente l'esecuzione di più istanze.
Dennis

mmm, stai invertendo la logica - mi piace! L'unico problema è che se qualcuno
capisce l'

Bene, sono stato fortunato che fosse una funzionalità che gli utenti avevano richiesto, quindi era WIN-WIN. Preferirei che "trovassero" una /allowMultipleInstancesbandiera piuttosto che quella piuttosto strana /restart.
Dennis

Sì, se consenti più istanze, questa è sicuramente una soluzione migliore :)
JohnIdol

@JohnIdol Nice. Penso che cambierò il mio flag in "-waitForProcessToExit" o qualcosa del genere, ma per il resto è una soluzione più elegante. In questo momento sono alle prese con un problema di ClickOnce con riferimento a un EXE da un altro EXE, e questo lo risolverebbe.
HiredMind

6

Metodo di avvio / uscita

// 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);

Sembra funzionare meglio di Application.Restart ();

Non sono sicuro di come questo gestisca se il tuo programma protegge da più istanze. La mia ipotesi è che sarebbe meglio lanciare un secondo .exe che si interrompe e quindi avvia l'applicazione principale per te.


2
Potrebbe non funzionare se l'applicazione è protetta da più istanze.
Majkinetor

Sì, ho la sensazione che chiamare Application.Exit () causi solo l'aggiunta di un messaggio a una coda da qualche parte che deve essere pompata, quindi il secondo bit di codice qui nella mia risposta probabilmente non funzionerebbe.
Adam Nofsinger,

Purtroppo questa tecnica non funziona (vorrei che lo facesse! È molto più semplice della mia soluzione). Funzionerà all'interno del debugger di Visual Studio ma non nella pratica. Vedi la mia risposta per una soluzione kludgy che funziona al di fuori del debugger.
HiredMind

HiredMind potrebbe avere ragione. Ho finito per optare per una soluzione di pattern Watchdog.
Adam Nofsinger

6

È semplice, devi solo chiamare i Application.Restart()metodi che tendono a richiamare la tua applicazione per il riavvio. Ma devi uscire dall'ambiente locale con i loro codici di errore:

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

è possibile creare un'enumerazione del codice di errore per utilizzarlo in modo efficace.
Un altro metodo è semplicemente uscire dall'applicazione e avviare il processo con il percorso eseguibile:

Application.exit();
System.Diagnostics.Process.Start(Application.ExecutablePath);

Ha funzionato bene per me, non è necessaria l'app watchdog nel mio caso.
user685590

3

Prova questo codice:

bool appNotRestarted = true;

Questo codice deve essere anche nella funzione:

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

3

Ho trovato un'altra soluzione, forse chiunque può usarla anche.

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

Il codice è semplificato, quindi prenditi cura delle eccezioni e altro;)


2

Stai dimenticando le opzioni / parametri della riga di comando che sono stati passati all'istanza attualmente in esecuzione. Se non li passi, non stai facendo un vero riavvio. Imposta il Process.StartInfocon un clone dei parametri del tuo processo, quindi inizia.

Ad esempio, se il processo è stato avviato come myexe -f -nosplash myfile.txt, il metodo verrà eseguito solo myexesenza tutti quei flag e parametri.


2

Volevo che la nuova applicazione si avviasse dopo la chiusura di quella vecchia.

Usare process.WaitForExit () per attendere l'arresto del proprio processo non ha senso. Sarà sempre il timeout.

Quindi, il mio approccio consiste nell'usare Application.Exit () quindi attendere, ma consentire l'elaborazione degli eventi, per un periodo di tempo. Quindi avvia una nuova applicazione con gli stessi argomenti della vecchia.

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 );
}

2

Puoi anche usare Restarter .

Restarter è un'applicazione che monitora e riavvia automaticamente programmi e applicazioni bloccati o bloccati. È stato originariamente sviluppato per monitorare e riavviare i server di gioco, ma farà il lavoro per qualsiasi console o programma o applicazione basata su form


1
Il link fornito non funziona più, ma penso che questa sia la stessa applicazione su 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 restituisce il percorso del file .exe dell'applicazione. Seguire l'ordine delle chiamate. Potresti metterlo in una clausola try-catch.


1

Che ne dici di creare un file bat, eseguire il file batch prima di chiuderlo e quindi chiudere l'istanza corrente.

Il file batch fa questo:

  1. attendere in un ciclo per verificare se il processo è terminato.
  2. avviare il processo.

Che è l'applicazione watchdog di un uomo povero, che descrivo un po 'più in dettaglio sopra. Il vantaggio principale di una vera applicazione watchdog è che gestirà anche se l'app originale muore senza essere in grado di far girare qualcosa.
Adam Nofsinger

@AdamNofsinger che vedo ora. Mi sono perso quel commento. Potresti voler modificare il tuo post con la soluzione che utilizzi.
AZ.

1

Ecco i miei 2 centesimi:

La sequenza Avvia nuova istanza-> Chiudi istanza corrente dovrebbe funzionare anche per le applicazioni che non consentono di eseguire più copie contemporaneamente poiché in questo caso alla nuova istanza potrebbe essere passato un argomento della riga di comando che indicherà che è in corso un riavvio quindi il controllo per altre istanze in esecuzione non sarà necessario. Aspettando che la prima istanza finisca effettivamente, venga implementata anche se è assolutamente imperativo che non ci siano due istanze in esecuzione in parallelo.


1

Il problema dell'utilizzo di Application.Restart () è che avvia un nuovo processo ma quello "vecchio" rimane ancora. Pertanto ho deciso di uccidere il vecchio processo utilizzando il seguente frammento di codice:

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

E funziona bene. Nel mio caso MATLAB e un'applicazione C # condividono lo stesso database SQLite. Se MATLAB sta utilizzando il database, l'app Form dovrebbe riavviarsi (+ Countdown) di nuovo, finché MATLAB non reimposta il suo bit di occupato nel database. (Solo per informazioni collaterali)


1

Temo che riavviare l'intera applicazione utilizzando Process stia affrontando il tuo problema nel modo sbagliato.

Un modo più semplice è modificare il file Program.cs per riavviare:

    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;
           }
        }
    }

1
Vale la pena ricordare che con questa soluzione è possibile riavviare l'applicazione X volte, quindi chiudere l'applicazione per evitare un ciclo infinito.
RooiWillie

Grazie @RooiWillie ho aggiunto un contatore per farlo, nel caso in cui il programma non possa uscire normalmente.
Andrew

0

Ho avuto un problema simile, ma il mio era correlato a una perdita di memoria non gestibile che non sono riuscito a trovare su un'app che deve essere eseguita 24 ore su 24, 7 giorni su 7. Con il cliente ho concordato che l'orario sicuro per riavviare l'app fosse 03:00 se il consumo di memoria era superiore al valore definito.

Ho provato Application.Restart, ma poiché sembra utilizzare un meccanismo che avvia una nuova istanza mentre è già in esecuzione, sono andato per un altro schema. Ho usato il trucco che il file system gestisce persistere fino a quando il processo che li ha creati non muore. Quindi, da L'applicazione, ho lasciato cadere il file sul disco e non l'ho Dispose()gestito. Ho usato il file per inviare l'eseguibile "me stesso" e anche la directory di partenza (per aggiungere flessibilità).

Codice:

_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()alla fine avrebbe avviato l'arresto dell'app e l'handle del file che ho usato StreamWriterqui sarebbe stato tenuto aperto fino a quando il processo non muore davvero. Poi...

Restarter.exe entra in azione. TENTA di leggere il file in modalità esclusiva, impedendogli di accedere fino a quando l'app principale non è morta, quindi avvia l'app principale, elimina il file ed esiste. Immagino che non possa essere più semplice:

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);
    }
}

0

Uso quanto segue e fa esattamente quello che stai cercando:

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);
}

0

per utilizzare Come logout è necessario terminare tutte le app da Ram Cache, quindi chiudere prima l'applicazione e poi rieseguirla

// facendo clic sul pulsante Logout

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

0

Potresti racchiudere il tuo codice all'interno di una funzione e quando è necessario il riavvio puoi semplicemente chiamare la funzione.


0

Prendiamo ad esempio un'applicazione che:

  1. Mentre l'applicazione non è registrata; (all'avvio) l'applicazione dovrebbe richiedere all'utente di registrare l'applicazione e creare un account di accesso.

  2. Una volta inviata la registrazione e create le credenziali di accesso; l'applicazione dovrebbe riavviarsi, verificare la registrazione e chiedere all'utente di effettuare il login con le credenziali inserite (in modo che l'utente possa accedere a tutte le funzionalità dell'applicazione).

Problema: compilando e avviando l'applicazione da Visual Studio; nessuna delle 4 alternative seguenti non riuscirà a svolgere i compiti richiesti.

/*
 * Note(s):
 * Take into consideration that the lines bellow don't represent a code block.
 * They are just a representation of possibilities,
 * that can be used to restart the application.
 */

Application.Restart();
Application.Exit();
Environment.Exit(int errorCode);
Process.GetCurrentProcess().Kill();

Quello che succede è: dopo aver creato la registrazione, accedere e chiamare Application.Restart (); l'applicazione (stranamente) riaprirà il modulo di registrazione e salterà i dati in un database (anche se la risorsa è impostata su "Copia se più recente").

Soluzione: creazione in batch dell'applicazione è stata (per me) una prova che una qualsiasi delle righe precedenti funzionava effettivamente come previsto. Solo non durante la creazione e l'esecuzione dell'applicazione con Visual Studio.

In primo luogo proverei a creare in batch l'applicazione; eseguirlo fuori da Visual Studio e verificare se Application.Restart () funziona effettivamente come previsto.

Controllare anche ulteriori informazioni sull'argomento di questo thread: Come riavviare l'applicazione C # WinForm?

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.