¿Por qué Application.Restart () no es confiable?

Usando el método Application.Restart() en C # debería reiniciar la aplicación actual: pero parece que esto no siempre está funcionando.

¿Hay alguna razón para este problema? ¿Puede alguien decirme por qué no funciona todo el tiempo?

Puede haber muchas razones para esto. No es que el método no funcione; más bien, muchas veces los progtwigdores olvidan que pusieron algo en su código que evitaría que la aplicación se apague automáticamente o se inicie. Dos ejemplos:

  • El evento de cierre en un formulario puede detener el cierre de una aplicación
  • Si está realizando una comprobación de un proceso que ya se está ejecutando, es posible que el anterior no se cierre lo suficientemente rápido como para permitir que se inicie el nuevo.

Revisa tu código para detectar problemas como ese. Si está viendo este comportamiento dentro de una aplicación en blanco, es más probable que sea un problema con la función real que su código.

Verifique el código fuente de reinicio de la aplicación de Microsoft.

En mi caso (NO instancia única), donde

 Application.Restart(); 

no funcionó

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

hizo el trabajo!

La única vez que me encontré con este tipo de problema es cuando en mi forma principal tenía un controlador de evento FormClosing personalizado, que realizaba la lógica y cancelaba el evento.

EDITAR:

Ahora me encontré con otra instancia y, según sus comentarios, posiblemente refleja lo que estaba experimentando.

Cuando ejecutaba una aplicación de instancia única, utilizando un Mutex, llamaba a Application.Restart() desde una ubicación bastante incrustada, que tenía que realizar una gran cantidad de tareas de limpieza. Por lo tanto, parece que el reinicio fue el lanzamiento de una nueva instancia antes de que la instancia anterior estuviera completa, por lo que el Mutex impedía el inicio de la nueva instancia.

En mi progtwig, tengo un mutex para asegurar que solo una instancia de la aplicación se ejecute en una computadora. Esto estaba causando que la aplicación recién iniciada no se iniciara porque el mutex no se había lanzado de manera oportuna. Como resultado, pongo un valor en Properties.Settings que indica que la aplicación se está reiniciando. Antes de llamar a Application.Restart() el valor de Properties.Settings se establece en verdadero . En Program.Main() también agregué un cheque para ese valor específico property.settings para que cuando true se restablezca a falso y haya un Thread.Sleep(3000);

En tu progtwig, puedes tener la lógica:

 if (ShouldRestartApp) { Properties.Settings.Default.IsRestarting = true; Properties.Settings.Default.Save(); Application.Restart(); } 

En Program.Main()

 [STAThread] static void Main() { Mutex runOnce = null; if (Properties.Settings.Default.IsRestarting) { Properties.Settings.Default.IsRestarting = false; Properties.Settings.Default.Save(); Thread.Sleep(3000); } try { runOnce = new Mutex(true, "SOME_MUTEX_NAME"); if (runOnce.WaitOne(TimeSpan.Zero)) { Application.EnableVisualStyles(); Application.SetCompatibleTextRenderingDefault(false); Application.Run(new Form1()); } } finally { if (null != runOnce) runOnce.Close(); } } 

Eso es.

Intenta bloquear antes de tirar. Así es como inicio un volcado de aplicaciones completo. Podría funcionar para usted, puede que no.

 Context.Application.Lock(); Context.Session.Abandon(); Context.Application.RemoveAll(); Context.Application.Restart(); Context.Application.UnLock(); 

Si la aplicación se inició por primera vez desde una ubicación de red y no está firmada (primero aparece el cuadro de diálogo de advertencia), no se reiniciará y solo se cerrará.

Prueba este código:

 bool appNotRestarted = true; 

Este código también debe estar en la función:

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

esto funcionó para mí, gracias.

Sé que este es un hilo viejo, pero encontré una solución. Espero que esto ayude a alguien más en necesidad.

Necesitaba una solución que activaría la secuencia de actualización durante el inicio de una aplicación ClickOnce desde el código. Applicatoin.Restart no hizo esto. Quería una forma de poder buscar una actualización y luego invocar el administrador de actualizaciones integrado para no tener que escribir uno personalizado.

  'VB Code Sample Dim strStart As String = System.Environment.GetFolderPath(Environment.SpecialFolder.StartMenu) & "\Programs\Folder\YourApplication.appref-ms" Application.Exit() Try Process.Start(strStart) Catch ex As Exception 'Do something with the exception End Try 

El único problema que veo con esta solución alternativa es que un usuario podría eliminar el acceso directo desde el menú de inicio. Si es una preocupación, podría escribir un código para copiar el enlace del menú de inicio a la carpeta que prefiera, preferiblemente en la carpeta de la aplicación ClickOnce. Esto es importante porque el ícono del menú de inicio para su aplicación no es .lnk o .exe, en realidad es un enlace .appref-ms. Ver ClickOnce .appref-ms más que un enlace al archivo .application? Este enlace explica esto con más detalle.

Este código funcionará con las aplicaciones ClickOnce SingleInstance.

 public static void ApplicationRestart(params string[] commandLine) { lock (SynchObj) { if (Assembly.GetEntryAssembly() == null) { throw new NotSupportedException("RestartNotSupported"); } if (_exiting) return; _exiting = true; if (Environment.OSVersion.Version.Major < 6) return; bool cancelExit = true; try { foreach (Form f in Application.OpenForms.OfType
().ToList()) { f.InvokeIfRequired(frm => { frm.FormClosing += (sender, args) => cancelExit = args.Cancel; frm.Close(); }); if (cancelExit) break; } if (cancelExit) return; Process.Start(new ProcessStartInfo { UseShellExecute = true, WorkingDirectory = Environment.CurrentDirectory, FileName = Application.ExecutablePath, Arguments = commandLine.Length > 0 ? string.Join(" ", commandLine) : string.Empty }); Application.Exit(); } finally { _exiting = false; } } }

Tengo este mismo problema con .Net Framework 4.7. La respuesta aceptada fue clave para mi éxito. Tenía un código en el evento FormClosing que llevaba un tiempo y detenía el proceso de reinicio. Lo que hice fue poner un centinela como este:

 If JustCloseIT = False Then 'all closing code, like logging the session log-out to a database and all those goodies we all do. End If 

solo entonces el Application.Restart () funcionó!