Как правильно выполнить перезапуск программы?
Цель такая: нужно обновить программу.
Алгоритм такой: программа скачивает обновление, проверяет на валидность, обозначает как-то что доступно обновление (например пишет ключ в реестр) и перезапускает себя (как firefox, например). При запуске программа проверяет ключ в реестре, и, если доступно обновление — заменяет файлы новыми и дальше работает в штатном режиме.
Остается два узких места: как обновить сам exe-шник?
и как организовать перезагрузку?
но если первую проблему можно как-то обойти: сам exe-шник представляет из себя лоадер, который умеет обновлять основную программу и загружать ее и сам не обновляется. А во-вторых, его можно переименовать во время работы и записать новую версию (не знаю только всегда и везде ли это будет работать?),
то со второй что-то никак не справиться.
Подскажите пожалуйста, как решить данную проблему или укажите как правильно делают обновления программ. Не обязательно подробно объяснять, главное дать пинок в нужном направлении
Заранее благодарен.
Системы семейства NT позволяют переименовать исполняемый файл даже если он сейчас загружен. Можно плясать от этого (простейший способ потребует записи ключика в RunOnce и перезагрузки машины).
А вообще я бы написал маленький екзешничек без использования VCL, сжал его UPX-ом и вложил в ресурс оновного исполняемого файла программы (добавит всего килобайт 10 к размеру). После загрузки обновления, отпочковываем от себя этот файлик, запускаем его с нужными параметрами, а сами завершаемся. Файлик же, дожидается нашего завершения, выполняет обновление всего что нужно, снова запускает программу с "секретным" параметром и тихо завершается. Программа при запуске с этим параметром первым делом дожидается завершения загрузчика, удаляет его и дальше работает как обычно.
Можно ничего не прятать, а просто держать этот загрузчик все время в каталоге программы, но тогда его самого обновить будет сложнее (это должна будет сделать сама программа перед его запуском).
Я бы сделал следующим образом.
Первый exe (лоадер) запускает основную программу, и не закрывается, ожидает сообщения. Сама программа, уловив, что нужно обновление, выдает сообщение об этом, посялает сообщение лоадеру (типа мол нужно обновить) и сама закрывается. Лоадер, же скачивает обновления и заного запускает программу. Просто и ясно.
Здравствуйте, bsigr, Вы писали:
B>Как правильно выполнить перезапуск программы? B>Цель такая: нужно обновить программу. B>Алгоритм такой: программа скачивает обновление, проверяет на валидность, обозначает как-то что доступно обновление (например пишет ключ в реестр) и перезапускает себя (как firefox, например). При запуске программа проверяет ключ в реестре, и, если доступно обновление — заменяет файлы новыми и дальше работает в штатном режиме.
B>Остается два узких места: как обновить сам exe-шник? B>и как организовать перезагрузку?
B>но если первую проблему можно как-то обойти: сам exe-шник представляет из себя лоадер, который умеет обновлять основную программу и загружать ее и сам не обновляется. А во-вторых, его можно переименовать во время работы и записать новую версию (не знаю только всегда и везде ли это будет работать?), B>то со второй что-то никак не справиться.
B>Подскажите пожалуйста, как решить данную проблему или укажите как правильно делают обновления программ. Не обязательно подробно объяснять, главное дать пинок в нужном направлении B>Заранее благодарен.
У меня работало так:
прога (exe), запускаясь, смотрит из какого каталога она запущена или в каком домене. если не из временного и не в домене, то копирует свой exe во временный каталог и запускает его, сама закрывается (это безоконная прога).
запустившись из временного каталога, прога создаёт домен приложения, включает его кеширование и загружает в него свой исходный exe из исходного каталога. кеширование позволяет программе самой перезаписывать свои файлы после того как они загружены.
загрузившись в домене, прога создаёт класс, создающий уже основное окно приложения из dll. таким образом exe'шнику не требуются остальные dll до этого момента, он имеет минимум кода и малый объём.
этот класс также ждёт здесь выхода из программы, после выхода проверяет, не установлен ли флаг перезапуска программы, и если установлен — вызывает функцию Application.Restart().
найдя обновление на сервере, приложение загружает файлы во временный каталог и предлагает юзеру их применить, либо тихо перезаписывает исходный набор файлов, т.к. они кешированы и доступ к ним не заблокирован.