Как можно заменить бинарный файл С++?
I задал этот вопрос в более общем контексте дизайна. Теперь я хотел бы поговорить о специфике.
Представьте, что у меня работает app.exe
. Он загружает update.exe
в ту же папку. Как app.exe
скопировать update.exe
поверх содержимого app.exe
? Я спрашиваю конкретно в контексте С++. Нужно ли мне какое-то третье приложение-посредник? Нужно ли беспокоиться о блокировке файлов? Каков наиболее надежный подход к самому бинарному обновлению (запрет на неприятный ИТ-персонал с экстремальными правами доступа к файлам)? В идеале я бы хотел увидеть портативные решения (Linux + OSX), но главная задача - Windows.
Ответы
Ответ 1
- Переместить/переименовать ваш запуск
app.exe
в app_old.exe
- Переместить/переименовать загруженный
update.exe
в app.exe
- При следующем запуске приложения будет использоваться обновление
Переименование запущенной i.e заблокированной dll/exe не является проблемой под окнами.
Ответ 2
Это функция операционной системы, а не С++.
На какой ОС вы работаете?
В Windows см. функцию MoveFileEx(), на linux просто перезапишите запущенное приложение (Замена исполняемого исполняемого файла в Linux)
Ответ 3
В Linux можно удалить исполняемый файл запущенной программы, следовательно:
- скачать
app.exe~
- удалить запуск
app.exe
- переименовать
app.exe~
в app.exe
В Windows невозможно удалить исполняемый файл запущенной программы, но можно переименовать его:
- скачать
app.exe~
- переименовать запуск
app.exe
в app.exe.old
- переименовать
app.exe~
в app.exe
- при перезапуске удалить
app.exe.old
Ответ 4
В Windows по крайней мере запущенное приложение блокирует свой собственный .exe файл и все статически связанные DLL файлы. Это не позволяет приложению обновляться напрямую, если приводит к нежелательной перезагрузке (если перезагрузка в порядке, приложение может передать флаг MOVEFILE_DELAY_UNTIL_REBOOT
в MoveFileEx и свободно "перезаписать" его собственный .exe, как и все-таки задерживается). Вот почему обычно приложения не проверяют наличие обновлений самостоятельно .exe, но они запускают прокладку, которая проверяет наличие обновлений, а затем запускает "реальное" приложение. Фактически "прокладка" может быть выполнена самой ОС, в силу правильно настроенного файла манифеста. Созданное приложение Visual Studio получает это как пакетный инструмент для сборщика, см. Развертывание ClickOnce для приложений Visual С++.
Типичное приложение для Linux не обновляет себя из-за многих многих разновидностей ОС. Большинство приложений распространяются как источник, запускаются через некоторую версию auto-hell для самостоятельной настройки и сборки, а затем устанавливаются через make install
(все они могут быть автоматизированы за пакетом). Даже приложения, которые распространяются как двоичные файлы для конкретного вкуса Linux, не копируют себя, а вместо этого устанавливают новую версию бок о бок, а затем они обновляют symbolic link
, чтобы "активировать" новую версию (опять же, программное обеспечение для управления пакетами может скрыть это).
Приложения OS X попадают либо в ведро Linux, если они относятся к вкусу Posix, либо в настоящее время попадают в ведро приложений Mac AppStore, которое обрабатывает обновления для вас.
На днях, когда ваш собственный самообновление никогда не достигнет изощренности ни одной из этих технологий (ClickOnce, RPM, AppStore) и предложит пользователю ожидаемое поведение при обнаружении, обновлении и удалении. Я бы пошел с потоком и использовал эти технологии на своих соответствующих платформах.
Ответ 5
Просто идея преодолеть проблему перезапуска. Как насчет создания программы, которая не нуждается в обновлении. Просто реализуйте его в структуре плагина, поэтому он является только узлом обновления, который сам загружает DLL файл со всеми функциональными возможностями вашей программы и вызывает основную функцию. Когда он обнаруживает обновление (возможно, в отдельном потоке), он сообщает дескриптору dll закрыть, заменяет файл и загружает новый.
Таким образом ваше приложение продолжает работать, пока оно обновляется (только файл dll перезагружается, но приложение продолжает работать).
Ответ 6
Используйте 3-й исполняемый файл updater, как и многие другие приложения.
- Загрузите новую версию.
- Запланируйте программу обновления для замены приложения новой версией.
- Закрыть главное приложение.
- Программа обновлений работает и выполняет работу.
- Updater запускает новую версию вашего приложения.
- Утилита обновления закрывается.