C++ 如何能够二进制替换自身?

发布于 2025-01-02 12:50:11 字数 433 浏览 0 评论 0原文

我之前在更一般的设计环境中问过这个问题。现在我想谈谈具体情况。

想象一下我正在运行 app.exe。它将 update.exe 下载到同一文件夹中。 app.exe 如何复制 update.exe 覆盖 app.exe 的内容?我是在 C++ 上下文中专门询问的。我需要某种第三种中介应用程序吗?我需要担心文件锁定吗?二进制更新本身最可靠的方法是什么(除非令人讨厌的 IT 人员拥有极端的文件权限)?理想情况下,我希望看到便携式解决方案(Linux + OSX),但 Windows 是主要目标。

I asked this question in a more general design context before. Now, I'd like to talk about the specifics.

Imagine that I have app.exe running. It downloads update.exe into the same folder. How would app.exe copy update.exe over the contents of app.exe? I am asking specifically in a C++ context. Do I need some kind of 3rd mediator app? Do I need to worry about file-locking? What is the most robust approach to a binary updating itself (barring obnoxious IT staff having extreme file permissions)? Ideally, I'd like to see portable solutions (Linux + OSX), but Windows is the primary target.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

善良天后 2025-01-09 12:50:11
  1. 将正在运行的 app.exe 移动/重命名为 app_old.exe
  2. 将下载的 update.exe 移动/重命名为 app.exe
  3. 下次启动应用程序时,将使用更新

重命名正在运行的 ie 锁定的 dll/exe 在 Windows 下不是问题。

  1. Move/Rename your running app.exe to app_old.exe
  2. Move/Rename your downloaded update.exe to app.exe
  3. With the next start of your application the update will be used

Renaming of a running i.e. locked dll/exe is not a problem under windows.

场罚期间 2025-01-09 12:50:11

在 Linux 上,可以删除正在运行的程序的可执行文件,因此:

  • 下载 app.exe~
  • 删除正在运行的 app.exe
  • 重命名 app.exe~ 到 app.exe

在 Windows 上,无法删除正在运行的程序的可执行文件,但可以对其进行重命名:

  • 下载 app.exe~
  • 重命名正在运行的 app.exeapp.exe.old
  • 重新启动时将 app.exe~ 重命名为 app.exe
  • 删除 app.exe.old

On Linux it is possible to remove the executable of a running program, hence:

  • download app.exe~
  • delete running app.exe
  • rename app.exe~ to app.exe

On Windows it is not possible to remove the executable of a running program, but possible to rename it:

  • download app.exe~
  • rename running app.exe to app.exe.old
  • rename app.exe~ to app.exe
  • when restarting remove app.exe.old
落叶缤纷 2025-01-09 12:50:11

这是一项操作系统功能 - 不是 C++ 功能。
你使用什么操作系统?

在 Windows 中,请参阅 MoveFileEx( ) 函数,在 Linux 上只需覆盖正在运行的应用程序 ( 替换 Linux 中正在运行的可执行文件

It's an operating system feature - not a C++ one.
What OS are you on?

In Windows see the MoveFileEx() function, on linux simply overwrite the running app ( Replacing a running executable in linux )

一袭白衣梦中忆 2025-01-09 12:50:11

在 Windows 上,至少运行的应用程序会锁定其自己的 .exe 文件和所有静态链接的 .dll 文件。这可以防止应用程序直接更新自身,如果需要阻止重新启动(如果重新启动正常,应用程序可以将 MOVEFILE_DELAY_UNTIL_REBOOT 标志传递给 MoveFileEx,并且可以自由地“覆盖” ' 它是自己的 .exe,无论如何都会被延迟)。这就是为什么应用程序通常不会在自己的 .exe 上检查更新,而是启动一个填充程序来检查更新,然后启动“真正的”应用程序。事实上,“垫片”甚至可以由操作系统本身通过正确配置的清单文件来完成。 Visual Studio 构建的应用程序将此作为预制件向导打包工具,请参阅 Visual C++ 应用程序的 ClickOnce 部署

由于操作系统的风格多种多样,典型的 Linux 应用程序不会自行更新。大多数应用程序都是作为源代码分发的,通过某些版本的 auto-hell 运行以进行自我配置和构建,然后通过 make install 进行自我安装(所有这些都可以在包后面自动化)。即使是针对特定 Linux 版本作为二进制文件分发的应用程序也不会自行复制,而是并排安装新版本,然后更新 符号链接来“激活”新版本(同样,包管理软件可能会隐藏这一点)。

OS X 应用程序要么属于 Posix 风格的 Linux 存储桶,要么现在属于为您处理更新的 Mac AppStore 应用程序存储桶。

我希望滚动您自己的自我更新永远不会达到这些技术(ClickOnce、RPM、AppStore)的复杂程度,并为用户提供相对于发现、升级和卸载的预期行为。我会顺其自然,在各自的平台上使用这些技术。

On Windows at least an application running is locking its own .exe file and all statically linked .dll files. This prevents an application from updating itself directly, at leads if it desires to prevent a re-boot (if re-boot is OK the app can pass in the MOVEFILE_DELAY_UNTIL_REBOOT flag to MoveFileEx and is free to 'overwrite' it's own .exe, as is delayed anyway). This is why typically applications don't check for updates on their own .exe, but they start up a shim that checks for updates and then launches the 'real' application. In fact the 'shim' can even be done by the OS itself, by virtue of a properly configured manifest file. Visual Studio built application get this as a prefab wizard packaged tool, see ClickOnce Deployment for Visual C++ Applications.

The typical Linux app doesn't update itself because of the many many many flavors of the OS. Most apps are distributed as source, run trough some version of auto-hell to self-configure and build themselves, and then install themselves via make install (all these can be automated behind a package). Even apps that are distributed as binaries for a specific flavor of Linux don't copy themselves over, but instead install the new version side-by-side and then they update a symbolic link to 'activate' the new version (again, a package management software may hide this).

OS X apps fall either into the Linux bucket if they are of the Posix flavor, or nowadays fall into the Mac AppStore app bucket which handles updates for you.

I would day that rolling your own self-update will never reach the sophistication of either of these technologies (ClickOnce, RPMs, AppStore) and offer the user the expected behavior vis-a-vis discovery, upgrade and uninstall. I would go with the flow and use these technologies in their respective platforms.

压抑⊿情绪 2025-01-09 12:50:11

只是克服“重新启动”问题的想法。制作一个不需要更新的程序怎么样?只需在插件结构中实现它,因此它只是一个更新主机,它本身会加载包含程序所需的所有功能的 .dll 文件,并在那里调用 main 函数。当它检测到更新时(可能在单独的线程中),它会告诉 dll 句柄关闭、替换文件并加载新文件。
这样,您的应用程序在更新自身的同时保持运行(仅重新加载 dll 文件,但应用程序保持运行)。

Just an idea to overcome the "restart" problem. How about making a program, that does not need to be updated. Just implement it in a plugin structure, so it is only an update host which itself loads a .dll file with all the functionality your program needs and calls the main function there. When it detects an update (possibly in a seperate thread), it tells the dll handle to close, replaces the file and loads the new one.
This way your application keeps running while it updates itself (only the dll file is reloaded but the application keeps running).

情绪失控 2025-01-09 12:50:11

像许多其他应用程序一样使用更新程序第三个可执行文件。

  • 下载新版本。
  • 安排您的更新程序将应用程序替换为新版本。
  • 关闭主应用程序。
  • 更新程序运行并完成工作。
  • 更新程序运行您的应用程序的新版本。
  • 更新程序退出。

Use an updater 3rd executable like many other apps.

  • Download new version.
  • Schedule your updater to replace the app with the new version.
  • Close main app.
  • Updater runs and does the work.
  • Updater runs new version of your app.
  • Updater quits.
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文