Tuve un problema similar, pero el mío estaba relacionado con la pérdida de memoria inmanejable que no pude encontrar en una aplicación que tiene que funcionar 24/7. Con el cliente acordé que el tiempo seguro para reiniciar la aplicación era a las 03:00 AM si el consumo de memoria superaba el valor definido.
Intenté Application.Restart
, pero como parece que usa algún mecanismo que inicia una nueva instancia mientras ya se está ejecutando, busqué otro esquema. Utilicé el truco que los controladores del sistema de archivos persisten hasta que muere el proceso que los creó. Entonces, desde la aplicación, dejé caer el archivo en el disco y no lo hice con el identificador Dispose()
. Usé el archivo para enviar el ejecutable 'myself' y el directorio de inicio también (para agregar flexibilidad).
Código:
_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()
al final sería empezar a pararse aplicación, y manejador de archivo que se utiliza para StreamWriter
aquí se mantiene abierto hasta que el proceso realmente muere. Entonces ...
Restarter.exe entra en acción. Intenta leer el archivo en modo exclusivo, evitando que tenga acceso hasta que la aplicación principal no esté muerta, luego inicia la aplicación principal, elimina el archivo y existe. Supongo que no puede ser más sencillo:
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);
}
}