Как бинарный C ++ может заменить себя? - PullRequest
28 голосов
/ 06 февраля 2012

Я задал этот вопрос в более общем контексте дизайна раньше. Теперь я хотел бы поговорить об особенностях.

Представь, что у меня app.exe работает. Он загружает update.exe в ту же папку. Как app.exe скопировать update.exe поверх содержимого app.exe? Я спрашиваю конкретно в контексте C ++. Нужно ли какое-то третье приложение посредника? Нужно ли беспокоиться о блокировке файлов? Каков наиболее надежный подход к самому двоичному обновлению (за исключением того, что у отвратительного ИТ-персонала есть экстремальные разрешения на доступ к файлам)? В идеале я хотел бы видеть портативные решения (Linux + OSX), но Windows является основной целью.

Ответы [ 6 ]

42 голосов
/ 06 февраля 2012
  1. Перемещение / переименование бега app.exe в app_old.exe
  2. Перемещение / переименование скачанного update.exe в app.exe
  3. При следующем запуске приложениябудет использоваться обновление

Переименование работающего, т.е. заблокированного dll / exe, не является проблемой под Windows.

9 голосов
/ 06 февраля 2012

В Linux можно удалить исполняемый файл работающей программы, следовательно:

  • загрузить app.exe~
  • удалить запущенное app.exe
  • переименоватьapp.exe~ до app.exe

В Windows невозможно удалить исполняемый файл работающей программы, но можно переименовать его:

  • скачать app.exe~
  • переименование работает app.exe в app.exe.old
  • переименование app.exe~ в app.exe
  • при перезапуске удалить app.exe.old
9 голосов
/ 06 февраля 2012

Это функция операционной системы, а не C ++.
В какой ОС вы работаете?

В Windows вы увидите функцию MoveFileEx () , в Linux просто перезапишите работающуюapp ( Замена работающего исполняемого файла в linux )

2 голосов
/ 07 января 2015

Просто идея преодоления проблемы «перезагрузки». Как насчет создания программы, которая не нуждается в обновлении. Просто внедрите его в структуру плагина, чтобы это был только узел обновлений, который сам загружает файл .dll со всеми функциями, необходимыми вашей программе, и вызывает там основную функцию. Когда он обнаруживает обновление (возможно, в отдельном потоке), он говорит закрывать дескриптор dll, заменяет файл и загружает новый. Таким образом, ваше приложение продолжает работать, пока оно само обновляется (перезагружается только файл dll, но приложение продолжает работать).

2 голосов
/ 06 февраля 2012

В Windows, по крайней мере, запущенное приложение блокирует свой собственный файл .exe и все статически связанные файлы .dll. Это не позволяет приложению обновлять себя напрямую, по проводам, если оно хочет предотвратить перезагрузку (если перезагрузка в порядке, приложение может передать флаг MOVEFILE_DELAY_UNTIL_REBOOT в MoveFileEx и может свободно «перезаписывать» свой собственный .exe). , так или иначе задерживается). Вот почему обычно приложения не проверяют наличие обновлений на собственном .exe, но запускают шим, который проверяет наличие обновлений, а затем запускает «настоящее» приложение. Фактически, "shim" может быть даже сделан самой ОС, благодаря правильно настроенному файлу манифеста. Приложение, созданное в Visual Studio, получает его как готовый инструмент, см. Развертывание ClickOnce для приложений Visual C ++ .

Типичное приложение Linux не обновляется само по себе из-за множества вариантов ОС. Большинство приложений распространяются как исходные, запускаются через какую-то версию auto-hell для самостоятельной настройки и сборки, а затем устанавливаются через make install (все это можно автоматизировать за пакетом). Даже приложения, которые распространяются в виде двоичных файлов для конкретной разновидности Linux, не копируют себя, а вместо этого устанавливают новую версию бок о бок, а затем обновляют symbolic link, чтобы «активировать» новая версия (опять же, программное обеспечение для управления пакетами может скрыть это).

Приложения OS X либо попадают в корзину Linux, если они имеют вкус Posix, либо в настоящее время попадают в корзину приложений Mac AppStore, которая обрабатывает обновления для вас.

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

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

Используйте 3-й исполняемый файл обновления, как и многие другие приложения.

  • Скачать новую версию.
  • Запланируйте обновление для замены приложения новой версией.
  • Закрыть главное приложение.
  • Программа обновления работает и работает.
  • Программа обновления запускает новую версию вашего приложения.
  • Программа обновления завершена.
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...