2012-02-06 3 views
23

I asked this question в более общем контексте дизайна. Теперь я хочу поговорить о специфике.Как заменить бинарный файл C++?

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

+0

Насколько я знаю, Windows не позволит вам перезаписать EXE во время работы программы. Это одна из самых неприятных вещей в Windows, imo. – unwind

+1

Как я уже говорил вам по этому другому вопросу, вы не можете перезаписать исполняемый файл exe. Я даже дал пошаговые инструкции о том, как сделать весь этот процесс. –

+0

@MooingDuck Я знаю! Я все еще ссылаюсь на ваш ответ как на высокий уровень дизайна. Я просто сужу рамки этого конкретного вопроса. Я уже доволен ответами. – TheBuzzSaw

ответ

35
  1. Переместить/Переименовать ваш ход app.exe к app_old.exe
  2. Move/Rename загруженного update.exe в app.exe
  3. С в следующем запуске приложения будет использовано обновление

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

+7

не знал, что вы можете переименовать исполняемый исполняемый файл! –

+0

Это работало очень хорошо для меня, исправляет проблему с курицей и яйцом с моим обновлением. – Boccobrock

9

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

В Windows см функции MoveFileEx(), на Linux просто переписать беговое приложение (Replacing a running executable in linux)

+0

+1 для связи по другую тему. Решение linux великолепен! – Nawaz

7

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

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

На окнах невозможно удалить исполняемый файл запущенной программы, но можно переименовать его:

  • загрузить app.exe~
  • переименования работает app.exe в app.exe.old
  • переименовывать app.exe~ в app.exe
  • при перезапуске удалить app.exe.old
2

В Windows по крайней мере, работает приложение блокировки свой EXE-файл и все статически связанные DLL-файлы. Это препятствует тому, чтобы приложение само обновлялось напрямую, если оно хочет предотвратить повторную загрузку (если перезагрузка в порядке, приложение может передать флаг MOVEFILE_DELAY_UNTIL_REBOOT в MoveFileEx и может «перезаписать» его собственный .exe, так как все равно откладывается). Вот почему обычно приложения не проверяют наличие обновлений самостоятельно .exe, но они запускают прокладку, которая проверяет наличие обновлений, а затем запускает «реальное» приложение. Фактически «прокладка» может быть выполнена самой ОС, в силу правильно настроенного файла манифеста. Созданное Visual Studio приложение получает это как инструмент для сборки готового набора, см. ClickOnce Deployment for Visual C++ Applications.

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

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

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

+0

Что касается приложений, которые работают постоянно? В моем случае приложение работает все время и активно исследует обновления (в дополнение к выполнению своих различных задач). Вы по-прежнему рекомендуем использовать те же самые инструменты обновления? – TheBuzzSaw

+0

Является ли пользователь приложения интерактивным или демоном/сервисом? Пользовательские интерактивные приложения, такие как ClickOnce, могут уведомить пользователя. Тип daemon/service зависит от среды: в корпоративной среде они обновляются администраторами, которые очень неохотно используют приложения для автоматической загрузки и запуска новых бит (непроверенных и, что более важно, потенциально скомпрометированных). Потребительский демон/служба будет иметь более легкое время для продажи преимуществ самообновления. –

+0

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

2

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

0

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

  • Загрузить новую версию.
  • Запланируйте обновление, чтобы заменить приложение новой версией.
  • Закрыть основное приложение.
  • Обновление работает и выполняет работу.
  • Updater запускает новую версию вашего приложения.
  • Updater завершает работу.
Смежные вопросы