Comment redémarrer mon application C # WinForm?

86

Développement d'une application WinForm C # .NET 2.0. Besoin de l'application pour se fermer et se redémarrer.

Application.Restart();

La méthode ci-dessus s'est avérée peu fiable .

Quelle est la meilleure façon de redémarrer l'application?

Adam Nofsinger
la source
3
Je suis curieux de savoir s'il est nécessaire de redémarrer votre application. Je n'ai jamais pensé à ce besoin auparavant. Quelle est votre situation?
JeffH
Notre situation particulière - une application de lecteur multimédia qui est censée parcourir certaines images et du contenu flash en boucle. Doit fonctionner pendant des jours et des jours sans redémarrage de la machine, et il n'y a pas de clavier / souris donc pas d'interaction de l'utilisateur. Si le programme se bloque (exception non gérée), vous devez redémarrer le programme, ne pas quitter ou afficher une erreur. stackoverflow.com/questions/773768/... Voyez cela pour savoir pourquoi le programme continue d'avoir des exceptions que je ne peux pas empêcher. :(
Adam Nofsinger
1
En fin de compte, une bien meilleure solution pour notre application était de développer une petite application Watchdog qui démarre (si elle n'est pas déjà en cours d'exécution) à partir de l'application principale. Le chien de garde vérifie simplement toutes les 10 secondes environ pour voir si l'application principale a toujours un processus en cours d'exécution, et si ce n'est pas le cas, il en démarre un. Simple, élégant et beaucoup plus robuste que d'essayer de redémarrer à partir de l'application principale.
Adam Nofsinger
2
Une autre raison de redémarrer est lorsque vous changez de langue ou avez téléchargé une mise à jour.
Andrew Truckle
1
Mais que faire si ... L'application de surveillance plante?
Metoniem

Réponses:

39

Malheureusement, vous ne pouvez pas utiliser Process.Start () pour démarrer une instance du processus en cours d'exécution. Selon la documentation Process.Start (): "Si le processus est déjà en cours d'exécution, aucune ressource de processus supplémentaire n'est démarrée ..."

Cette technique fonctionnera correctement sous le débogueur VS (car VS fait une sorte de magie qui fait que Process.Start pense que le processus n'est pas déjà en cours d'exécution), mais échouera s'il n'est pas exécuté sous le débogueur. (Notez que cela peut être spécifique au système d'exploitation - il me semble que je me souviens que dans certains de mes tests, cela a fonctionné sur XP ou Vista, mais je me souviens peut-être de l'avoir exécuté sous le débogueur.)

Cette technique est exactement celle utilisée par le dernier programmeur du projet sur lequel je travaille actuellement, et j'essaie de trouver une solution de contournement pour cela depuis un certain temps. Jusqu'à présent, je n'ai trouvé qu'une seule solution, et cela me semble juste sale: démarrer une 2ème application, qui attend en arrière-plan la fin de la première application, puis relance la 1ère application. Je suis sûr que ça marcherait, mais, beurk.

Edit: L'utilisation d'une 2ème application fonctionne. Tout ce que j'ai fait dans la deuxième application était:

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

(Ceci est un exemple très simplifié. Le vrai code a beaucoup de contrôle de cohérence, de gestion des erreurs, etc.)

HiredMind
la source
Je suis d'accord avec HiredMind, et je suis allé moi-même avec la même implémentation "Watchdog program" peu après avoir écrit la réponse. Désolé, j'aurais dû revenir ici et mettre à jour. Je ne pense pas que ça devrait être trop horriblement moche / dégueulasse / sale. Le modèle de programme Watchdog est assez largement utilisé.
Adam Nofsinger le
Vous n'avez pas réellement besoin d'une deuxième application sur le disque ... vous pouvez utiliser un script et le générer à la volée avec un nom temporaire ... Je pense que cela peut atténuer votre sentiment de culpabilité d'avoir une deuxième application dans le but de redémarrer la vôtre ... Ou vous pouvez "émettre" une application C # entière, la compiler, la sauvegarder sur le disque et l'exécuter (pensée sale et sale) ..
Loudenvier
Le premier paragraphe n'est pas correct: Process.Startne regarde pas la liste des processus OS en cours d'exécution. Cette déclaration de documentation ne parle que de cette instance d'objet de la Processclasse. La Processclasse peut être attachée à un processus en cours d'exécution, mais elle peut également être dans un état non démarré. À mon avis, c'est une erreur de conception. La meilleure pratique, IMO, est de ne jamais réutiliser une Process instance et de la démarrer immédiatement après sa création. Idéalement, utilisez la Process.Startméthode statique . Ensuite, ce défaut de documentation et de conception n'entre jamais en jeu.
usr
Le code présenté ici n'est pas non plus fiable à cause de WaitForExit(1000). Mais toute l'attente n'est pas nécessaire pour démarrer un nouveau processus. Il peut s'agir d'un comportement supplémentaire que vous souhaitez, mais il n'est pas nécessaire de démarrer un nouveau processus.
usr
Je ne sais pas pour le moment, mais il y a neuf ans (euh) c'était définitivement correct. :-)
HiredMind
72

Une approche beaucoup plus simple qui a fonctionné pour moi est:

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

Cela préserve les arguments de la ligne de commande et fonctionne malgré les gestionnaires d'événements qui empêcheraient normalement l'application de se fermer.

L'appel Restart () tente de quitter, démarre quand même une nouvelle instance et revient. L'appel Exit () met alors fin au processus sans donner à aucun gestionnaire d'événements une chance de s'exécuter. Il y a une très brève période pendant laquelle les deux processus sont en cours d'exécution, ce qui n'est pas un problème dans mon cas, mais peut-être dans d'autres cas.

Le code de sortie 0 dans Environment.Exit(0);spécifie un arrêt propre. Vous pouvez également quitter avec 1 pour indiquer qu'une erreur s'est produite.

EMP
la source
Simple mais fiable. Cela devrait être la réponse acceptée. J'essayais de mettre en œuvre une fonctionnalité de déconnexion qui viderait toutes les variables globales et donnerait l'impression que l'application venait de démarrer. J'allais simplement montrer le panneau de connexion et réinitialiser toutes les variables globales contenant des informations importantes de la base de données à rien. Cela a rendu la vie beaucoup plus simple. Merci!
DavidG
System.Windows.Forms.Application.Restart () fonctionne également pour les applications WPF. Testé avec le système d'exploitation Windows 10.
NthDeveloper
Whaaaat?! Vous kiddin ... non? C # <3. Gardez à l'esprit que, par défaut, cela ne déclenchera pas d' OnClose()événements de formulaire et autres.
F8ER
56

Si vous êtes dans le formulaire principal de l'application, essayez d'utiliser

System.Diagnostics.Process.Start( Application.ExecutablePath); // to start new instance of application
this.Close(); //to turn off current app
Darqer
la source
7
C'est similaire, mais différent. Application.Exit n'a pas fonctionné de moi, et this.Close () a fait le travail.
Darqer
1
May Enviorment.Exit(0)fera également le travail.
Dwza
2
Enviorment.Exitest une sortie sale et assez invasive car elle empêche l'exécution du code de nettoyage d'application. Pas le bon choix la plupart du temps.
usr
16

Je suis peut-être en retard à la fête mais voici ma solution simple et cela fonctionne comme un charme avec chaque application que j'ai:

        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
la source
Fonctionne très bien sur Win-7-x64 et Win-XP-x32. Je ne vois rien sur les contraintes dans la documentation . Cela devrait être la réponse acceptée.
Bitterblue
@Bitterblue Le lien vers les documents que vous avez publiés indique "Si le processus est déjà en cours d'exécution, aucune ressource de processus supplémentaire n'est démarrée." C'est la troisième ligne de la section des remarques. J'aurais aimé que ce ne soit pas ainsi, mais c'est le cas.
HiredMind du
@HiredMind Je suppose que nous pourrions discuter de ce que signifie «contraintes» pour chacun de nous. Mais la section est intitulée «Remarques» et non «Contraintes». Alors je peux vivre avec. Et pourquoi souhaiteriez- vous que ce ne soit pas le cas? Avez-vous rencontré des problèmes avec cela? Parce que je ne l'ai pas fait. Fonctionne parfaitement pour moi.
Bitterblue du
@HiredMind Ce n'est rien de personnel ou quoi que ce soit, mais l'idée d'utiliser une deuxième application ou un script juste pour redémarrer mon application C # me répugne. Win7 exécute cette méthode en mode Release parfaitement jusqu'à présent (je l'utilise pour redémarrer mon application lorsque l'utilisateur change de langue = rien d'important). Je préfère donc dire à l'utilisateur de redémarrer l'application manuellement plutôt que d'utiliser des méthodes que je n'approuve pas moi-même. J'ai utilisé des scripts dans le passé et je n'ai pas du tout aimé.
Bitterblue du
@BitterBlue Je suis d'accord pour dire que l'utilisation d'une deuxième application est nul - je l'ai dit dans ma réponse. Mais avez-vous essayé la méthode d'application unique en dehors du débogueur? Cela ne fonctionnait pas sur certaines versions de Windows lorsque cette réponse était restée, et le mode Release ou Debug n'avait rien à voir avec cela. Si cela fonctionne pour vous, tant mieux! Mais j'ai été mordu par ce problème et ce que j'ai obtenu, ce sont des centaines d'utilisateurs en colère.
HiredMind
12

J'ai eu le même problème exact et j'avais aussi une exigence pour éviter les instances en double - je propose une solution alternative à celle que HiredMind propose (qui fonctionnera bien).

Ce que je fais, c'est démarrer le nouveau processus avec le processId de l'ancien processus (celui qui déclenche le redémarrage) comme argument de ligne 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);

Ensuite, lorsque la nouvelle application démarre, j'analyse d'abord les arguments de la ligne cm et vérifie si l'indicateur de redémarrage est là avec un processId, puis j'attends que le processus se termine:

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

Je ne montre évidemment pas tous les contrôles de sécurité que j'ai en place, etc.

Même si ce n'est pas idéal - je trouve que c'est une alternative valable pour que vous n'ayez pas à avoir en place une application séparée juste pour gérer le redémarrage.

JohnIdol
la source
1
IMHO qu'il existe une solution plus soignée à cela. J'ai également une exigence d'avoir une instance unique et de permettre à l'utilisateur de redémarrer l'application (par exemple, lorsqu'elle plante). J'ai presque implémenté votre solution, mais il m'est apparu qu'il serait préférable d'ajouter simplement un argument de ligne de commande différent permettant à plusieurs instances de s'exécuter.
Dennis
mmm, vous inversez la logique - j'aime ça! Le seul problème est que si quelqu'un comprend l'argument de ligne cmd qui autorise plusieurs instances, des choses étranges peuvent se produire: D
JohnIdol
Eh bien, j'ai eu la chance que c'était une fonctionnalité que les utilisateurs avaient demandée, donc c'était WIN-WIN. Je préférerais qu'ils «trouvent» un /allowMultipleInstancesdrapeau plutôt qu'un drapeau plutôt étrange /restart.
Dennis
Oui, si vous autorisez plusieurs instances, c'est une meilleure solution à coup sûr :)
JohnIdol
@JohnIdol Nice. Je pense que je vais changer mon drapeau en "-waitForProcessToExit" ou quelque chose, mais sinon c'est une solution plus élégante. En ce moment, je suis aux prises avec un problème ClickOnce avec le référencement d'un EXE à partir d'un autre EXE, et cela résoudrait cela.
HiredMind
6

Méthode Start / Exit

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

Cela semble mieux fonctionner que Application.Restart ();

Je ne sais pas comment cela gère si votre programme protège contre plusieurs instances. Je suppose que vous feriez mieux de lancer un deuxième .exe qui met en pause puis démarre votre application principale pour vous.

Adam Nofsinger
la source
2
Cela peut ne pas fonctionner si l'application est protégée contre plusieurs instances.
majkinetor
Yah, j'ai le sentiment d'appeler Application.Exit () ne fait qu'ajouter un message à une file d'attente quelque part qui doit être pompée, donc le deuxième bit de code ici dans ma réponse ne fonctionnerait probablement pas.
Adam Nofsinger
Malheureusement cette technique ne fonctionne pas (j'aurais aimé qu'elle le fasse! C'est tellement plus simple que ma solution). Cela fonctionnera dans le débogueur Visual Studio mais pas dans la pratique. Voir ma réponse pour une solution kludgy qui fonctionne en dehors du débogueur.
HiredMind
HiredMind a peut-être raison. J'ai fini par choisir une solution de modèle Watchdog.
Adam Nofsinger
6

C'est simple, il vous suffit d'appeler les Application.Restart()méthodes qui ont tendance à appeler votre application pour le redémarrage. Mais vous devez avoir à quitter l'environnement local avec leurs codes d'erreur:

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

vous pouvez créer une énumération de code d'erreur pour que vous puissiez l'utiliser efficacement.
Une autre méthode consiste simplement à quitter l'application et à démarrer le processus avec le chemin de l'exécutable:

Application.exit();
System.Diagnostics.Process.Start(Application.ExecutablePath);
Sonu
la source
A bien fonctionné pour moi, pas besoin de l'application de surveillance dans mon cas.
user685590
3

Essayez ce code:

bool appNotRestarted = true;

Ce code doit également être dans la fonction:

if (appNotRestarted == true) {
    appNotRestarted = false;
    Application.Restart();
    Application.ExitThread();
}
ferhatayhan
la source
3

J'ai trouvé une autre solution, peut-être que n'importe qui peut l'utiliser aussi.

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

Le code est simplifié, alors faites attention aux exceptions et tout ça;)

br4inp4in
la source
2

Vous oubliez les options / paramètres de ligne de commande qui ont été transmis à votre instance en cours d'exécution. Si vous ne les transmettez pas, vous n'effectuez pas un véritable redémarrage. Définissez le Process.StartInfoavec un clone des paramètres de votre processus, puis démarrez.

Par exemple, si votre processus a été démarré en tant que myexe -f -nosplash myfile.txt, votre méthode ne s'exécuterait que myexesans tous ces indicateurs et paramètres.

Erich Mirabal
la source
2

Je voulais que la nouvelle application démarre après la fermeture de l'ancienne.

Utiliser process.WaitForExit () pour attendre l'arrêt de votre propre processus n'a aucun sens. Il expirera toujours.

Donc, mon approche est d'utiliser Application.Exit () puis d'attendre, mais d'autoriser le traitement des événements, pendant un certain temps. Ensuite, démarrez une nouvelle application avec les mêmes arguments que l'ancienne.

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
la source
2

Vous pouvez également utiliser Restarter .

Restarter est une application qui surveille et redémarre automatiquement les programmes et applications bloqués ou bloqués. Il a été développé à l'origine pour surveiller et redémarrer les serveurs de jeux, mais il fera le travail pour n'importe quelle console ou programme ou application basé sur un formulaire.

Daniel Rose
la source
1
Le lien fourni ne fonctionne plus, mais je pense que c'est la même application sur 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 renvoie le chemin du fichier .exe de votre application Veuillez suivre l'ordre des appels. Vous voudrez peut-être le placer dans une clause try-catch.

Olfredos6
la source
1

Que diriez-vous de créer un fichier de batte, d'exécuter le fichier de commandes avant de fermer, puis de fermer l'instance actuelle.

Le fichier de commandes fait ceci:

  1. attendez dans une boucle pour vérifier si le processus est terminé.
  2. démarrer le processus.
AZ.
la source
Quelle est l'application de surveillance d'un pauvre homme, que je décris un peu plus en détail ci-dessus. Le principal avantage d'une véritable application de surveillance est qu'elle gérera même si l'application d'origine meurt sans pouvoir faire tourner quelque chose.
Adam Nofsinger
@AdamNofsinger Je vois maintenant. J'ai manqué ce commentaire. Vous voudrez peut-être modifier votre message avec la solution que vous utilisez.
AZ.
1

Voici mes 2 cents:

La séquence Start New Instance-> Close Current Instance devrait fonctionner même pour les applications qui ne permettent pas d'exécuter plusieurs copies simultanément, car dans ce cas, la nouvelle instance peut recevoir un argument de ligne de commande qui indiquera qu'un redémarrage est en cours il ne sera donc pas nécessaire de vérifier les autres instances en cours d'exécution. En attendant que la première instance se termine, je suis également implémenté s'il est absolument impératif qu'aucune instance ne soit exécutée en parallèle.

Felix Prangishvili
la source
1

Je crains que le redémarrage de l'ensemble de l'application à l'aide de Process n'aborde votre problème de la mauvaise manière.

Un moyen plus simple consiste à modifier le fichier Program.cs pour redémarrer:

    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
la source
1
Il est à noter qu'avec cette solution, vous pouvez redémarrer l'application X fois, puis quitter l'application pour éviter une boucle infinie.
RooiWillie
Merci @RooiWillie J'ai ajouté un compteur pour faire exactement cela, au cas où le programme ne pourrait pas quitter normalement.
Andrew
0

J'ai eu un problème similaire, mais le mien était lié à une fuite de mémoire ingérable que je ne pouvais pas trouver sur une application qui doit fonctionner 24 heures sur 24, 7 jours sur 7. Avec le client, j'ai convenu que le moment sûr pour redémarrer l'application était 03h00 si la consommation de mémoire dépassait la valeur définie.

J'ai essayé Application.Restart, mais comme il semble utiliser un mécanisme qui démarre une nouvelle instance alors qu'elle est déjà en cours d'exécution, j'ai opté pour un autre schéma. J'ai utilisé l'astuce que le système de fichiers gère jusqu'à ce que le processus qui les a créés meurt. Donc, à partir de l'application, j'ai déposé le fichier sur le disque, et je n'ai pas Dispose()la poignée. J'ai utilisé le fichier pour envoyer l'exécutable «moi-même» et le répertoire de départ également (pour ajouter de la flexibilité).

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()à la fin, cela déclencherait l'arrêt de l'application et le descripteur de fichier que j'utilisais StreamWriterici serait maintenu ouvert jusqu'à ce que le processus meure vraiment. Ensuite...

Restarter.exe entre en action. Il ESSAYE de lire le fichier en mode exclusif, l'empêchant d'accéder jusqu'à ce que l'application principale ne soit pas morte, puis démarre l'application principale, supprime le fichier et existe. Je suppose que cela ne peut pas être plus simple:

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
la source
0

J'utilise ce qui suit et il fait exactement ce que vous recherchez:

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
la source
0

Pour utiliser En tant que déconnexion, vous devez mettre fin à toutes les applications de Ram Cache, fermez d'abord l'application, puis réexécutez-la

// en cliquant sur le bouton de déconnexion

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

Le problème de l'utilisation d' Application.Restart () est qu'il démarre un nouveau processus mais que «l'ancien» est toujours en place. C'est pourquoi j'ai décidé de tuer l'ancien processus en utilisant l'extrait de code suivant:

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

Et cela fonctionne bien. Dans mon cas, MATLAB et une application C # partagent la même base de données SQLite. Si MATLAB utilise la base de données, le Form-App doit redémarrer (+ Compte à rebours) à nouveau, jusqu'à ce que MATLAB réinitialise son bit occupé dans la base de données. (Juste pour information secondaire)

Ricardo Fercher
la source
0

Vous pouvez inclure votre code dans une fonction et lorsque le redémarrage est nécessaire, vous pouvez simplement appeler la fonction.

Petr Mach
la source