Перезапуск приложения WinForm? - PullRequest
2 голосов
/ 23 августа 2010

У меня есть приложение, которое работает на моем компьютере и компьютерах моих коллег на работе.Иногда я отправляю обновления для этого приложения и хочу, чтобы приложение обнаруживало это автоматически (возможно, через базу данных), закрывалось и снова открывалось для установки новых обновлений.

Я знаю, как я могу закрыть приложение, но не знаю, как я могу открыть его заново, потому что, когда оно не работает, я не знаю, как выполнить какой-либо код ...

Ответы [ 5 ]

3 голосов
/ 23 августа 2010

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

Единственный способ определить, было ли приложение должно быть обновлено, а рассматриваемое приложение - этовсе еще работает, это опросить файл развертывания ClickOnce на сервере и сравнить номер версии с текущим развертыванием.Не рекомендуется.

Редактировать:

Еще один способ гарантировать, что ваши пользователи всегда имеют самую последнюю версию, - это не включать постоянный файл развертывания и заставить пользователя всегда запускаться изстартовая страница на вашем сайте.Это будет только блюдо последней и лучшей версии.

1 голос
/ 23 августа 2010

Процесс, который вам действительно необходим, выглядит примерно так:

  1. Приложение обнаруживает, что требуется обновление, выполняет приложение обновления и затем завершает работу.
  2. Обновление загружает и устанавливает приложениеобновление
  3. Приложение обновления перезапускает «основное» приложение

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

Чтобы запустить другой процесс, вам нужно выполнить код System.Diagnostics.Process.Start(), например:

Process p = new Process();
p.StartInfo.FileName = "C:\\Windows\\System32\cmd.exe";
p.Start();
1 голос
/ 23 августа 2010

Как насчет создания небольшого обновления приложения.Когда ваше приложение обнаруживает обновление, оно запускает приложение обновления и закрывается само.Приложение обновления загружает и устанавливает обновление, а затем перезапускает основное приложение и закрывает себя.

В качестве альтернативы, если приложение может обновляться при открытии, зачем его выключать?Разве он не может просто высвободить ресурсы, которые он использует, и т. Д. И выполнить обновление.

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 голосов
/ 23 августа 2010

Если вы используете ClickOnce (а ваш тег подсказывает, что вы?), То вы можете настроить его так, чтобы ваше приложение проверяло наличие обновлений при запуске.

...