Как перезапустить приложение C # WinForm? - PullRequest
77 голосов
/ 23 апреля 2009

Разработка приложения WinForm для C # .NET 2.0. Нужно приложение, чтобы закрыть и перезапустить себя.

Application.Restart();

Приведенный выше метод имеет значение , которое оказалось ненадежным .

Как лучше перезапустить приложение?

Ответы [ 20 ]

2 голосов
/ 23 апреля 2009

Вы забываете параметры / параметры командной строки, которые были переданы в текущий запущенный экземпляр. Если вы не передадите их, вы не выполните настоящий перезапуск. Установите Process.StartInfo с помощью клона параметров вашего процесса, а затем начните.

Например, если ваш процесс был запущен как myexe -f -nosplash myfile.txt, ваш метод будет выполнять только myexe без всех этих флагов и параметров.

2 голосов
/ 01 июля 2016
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 возвращает путь к файлу приложения .exe .exe Пожалуйста, следуйте порядку звонков. Возможно, вы захотите поместить его в предложение try-catch.

2 голосов
/ 09 апреля 2011

Вы также можете использовать Restarter .

Restarter - это приложение, которое автоматически отслеживает и перезапускает сбойные или зависшие программы и приложения. Первоначально он был разработан для мониторинга и перезапуска игровых серверов, но он будет работать для любой консоли или программы на основе форм или приложения

1 голос
/ 21 февраля 2014

Боюсь, что перезапуск всего приложения с помощью Process неправильно подходит к вашей проблеме.

Более простой способ - изменить файл Program.cs для перезапуска:

    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 голос
/ 27 марта 2012

Вот мои 2 цента:

Последовательность Start New Instance-> Close Current Instance должна работать даже для приложений, которые не позволяют запускать несколько копий одновременно, поскольку в этом случае новому экземпляру может быть передан аргумент командной строки, который будет указывать, что существует выполняется повторный запуск, поэтому проверка наличия других экземпляров не требуется. Ожидание, пока первый экземпляр фактически завершит мой, будет также реализовано, если абсолютно необходимо, чтобы никакие два экземпляра не работали параллельно.

0 голосов
/ 31 декабря 2015

для использования в качестве выхода из системы вам необходимо завершить все приложения из Ram Cache так закройте сначала приложение, а затем снова запустите его

// при нажатии кнопки выхода из системы

foreach(Form frm in Application.OpenForms.Cast<Form>().ToList())
        {
            frm.Close();
        }
System.Diagnostics.Process.Start(Application.ExecutablePath);
0 голосов
/ 28 октября 2015

Я использую следующее, и оно делает именно то, что вы ищете:

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 голосов
/ 09 апреля 2011

У меня была похожая проблема, но моя была связана с неуправляемой утечкой памяти, которую я не смог найти в приложении, которое должно работать 24/7. С клиентом я согласился, что безопасное время для перезапуска приложения было 3:00 утра, если потребление памяти превышало определенное значение.

Я пытался Application.Restart, но, поскольку он, похоже, использует какой-то механизм, который запускает новый экземпляр, когда он уже запущен, я выбрал другую схему. Я использовал прием, который обрабатывает файловая система, до тех пор, пока процесс, который их создал, не прекратит работу. Итак, из приложения я сбросил файл на диск, а не Dispose() дескриптор. Я использовал этот файл для отправки исполняемого и начального каталога «себя» (для большей гибкости).

Код:

_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() в конце может привести к закрытию приложения, и дескриптор файла, который я использовал для StreamWriter, будет оставаться открытым до тех пор, пока процесс не прекратится. Тогда ...

Restarter.exe вступает в действие. Он пытается прочитать файл в монопольном режиме, не давая ему получить доступ до тех пор, пока основное приложение не исчезнет, ​​затем запускает основное приложение, удаляет файл и существует. Я думаю, что это не может быть проще:

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 голосов
/ 15 февраля 2017

Проблема использования Application.Restart () в том, что он запускает новый процесс, но «старый» все еще остается. Поэтому я решил убить старый процесс, используя следующий фрагмент кода:

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

И все работает хорошо. В моем случае MATLAB и приложение C # используют одну и ту же базу данных SQLite. Если MATLAB использует базу данных, Form-App должен перезапустить (+ обратный отсчет) снова, пока MATLAB не сбросит бит занятости в базе данных. (Только для дополнительной информации)

0 голосов
/ 15 декабря 2011

Как насчет создания bat-файла, запустите batch-файл перед закрытием и затем закройте текущий экземпляр.

Пакетный файл делает это:

  1. ждать в цикле, чтобы проверить, завершился ли процесс.
  2. запустить процесс.
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...