如何使文件自我更新(Native C ++)

时间:2009-06-17 20:25:54

标签: c++ windows native

我正在使用Microsoft Visual Studio 2008和Windows目标部署。我如何使文件“自我更新”?我已经将“通过网络传输”部分放下了,但是如何让可执行文件自行写入呢?

基本上,我想为包含自动更新程序的目录编写自动更新程序,并且更新程序需要更新目录中的所有内容。

也许在文件锁释放之前将更改挂起到文件的方法可行。如果我这样做,我可能会用热补丁来跟进。

7 个答案:

答案 0 :(得分:5)

编写新的可执行文件并删除或保存旧的可执行文件的副本 - 您可以通过网络发送差异并使用第三个程序,即更新监视器或其他任何程序来应用它。它只是一个小脚本,可以在远程应用程序实现更新可用时启动。更新程序可以将自身重命名为$ UPDATER_OLD_VERSION或其他任何内容,使用适当的名称编写自身的更新副本,然后在运行新的更新程序时,检查应用程序目录中是否存在名为$ UPDATER_OLD_VERSION的文件并将其删除。所有其他文件都可以更新/覆盖。

答案 1 :(得分:4)

这就是我最近的做法。旧程序运行和新编程运行有一个简短的重叠。它利用了您可以重命名当前可执行文件并在关闭旧文件之前将新文件放在适当位置的技巧。这不是100%的安全故障,但是如果CopyFile失败,这可能会“堵塞”您的应用程序的唯一方法。

#include <windows.h>
#include <iostream>
#include <fstream>

void UpgradeService::UpgradeSelf() {

  std::string temp = root         + "\\myprogram_tmp.exe";
  remove(temp.c_str()); // ignore return code

  std::string src = upgradeFolder + "\\myprogram.exe";
  std::string dst = root          + "\\myprogram.exe";


  rename(dst.c_str(),temp.c_str());
  CopyFile(src.c_str(),dst.c_str(),false);
  static char buffer[512];
  strcpy(buffer,dst.c_str());

  /* CreateProcess API initialization */
  STARTUPINFO siStartupInfo;
  PROCESS_INFORMATION piProcessInfo;
  memset(&siStartupInfo, 0, sizeof(siStartupInfo));
  memset(&piProcessInfo, 0, sizeof(piProcessInfo));
  siStartupInfo.cb = sizeof(siStartupInfo);

  ::CreateProcess(buffer, // application name/path
    NULL, // command line (optional)
    NULL, // no process attributes (default)
    NULL, // default security attributes
    false,
    CREATE_DEFAULT_ERROR_MODE | CREATE_NEW_CONSOLE,
    NULL, // default env
    NULL, // default working dir
    &siStartupInfo,
    &piProcessInfo);


  ::TerminateProcess( GetCurrentProcess(),0);
  ::ExitProcess(0); // exit this process

  // this does not return.
}

答案 2 :(得分:3)

一般情况下,您无法在应用运行时对其进行修改。您需要关闭原始程序并从其他位置进行修改。

答案 3 :(得分:2)

我使用静默启动的InnoSetup setup.exe并在开始安装新文件之前关闭我的应用程序。我不得不添加自定义Pascal [代码]部分,以确保一切都关闭但它完成了工作。

答案 4 :(得分:2)

您无法在文件执行时覆盖该文件,但您可以重命名该文件。在我的更新程序中,我将现有的exe重命名为有意义的东西(oldname_dateandtime),然后将新副本写入。然后自动关闭我们的系统并从服务重新启动它。当应用程序启动时,它就是正在运行的新版本。

答案 5 :(得分:0)

当我制作更新程序时,我应该将程序分开几个。主要原因与您想要做的一样。简单地说,B更新目标应用 A和A更新B. 我试图找到另一种方式,但我所做的是制作了一个超小而简单的更新程序。 :(

答案 6 :(得分:0)

我认为你在谈论文件版本和更新程序。 正如您所说,您需要autoupdater。因此,您需要创建一个监视安装目录的服务,并将磁盘上的文件版本与服务器进行比较。

一旦发生不匹配,您可以向服务器询问最新数据。如果要替换的文件正在使用中,则必须在下次重新启动时将其标记为删除/取消注册,您可以使用注册表提及这些文件。

您可以复制缓存中的所有文件,稍后在重新启动时将其复制到安装目录。