9

我们正在尝试一次将更新推送到多台服务器,我的经理发现可以重命名正在运行的 .exe 文件。使用该知识,他想重命名正在运行的 exe 并复制所述 exe 的新版本,这样任何运行 foo.exe 内存副本的人都可以,并且任何打开指向 foo.exe 的快捷方式的人都将获得一个新副本应用了更新。

我想我需要澄清一下,他并不指望旧副本会神奇地更新,他只是希望他们继续运行旧副本,直到他们再次打开 exe,在这种情况下,它将打开具有名称的新副本旧的。

它有时会抛出该文件正在他的程序中使用的异常,但如果他尝试在循环中重命名它,它最终会成功。在我的机器上,即使在循环中,我也无法让它工作。

我的第一个也是主要的问题是:这样做是否可以接受。重命名正在运行的可执行文件是否应该是一个有效的场景?

其次,如果这是一个有效的场景,那么如何可靠地做到这一点?我们目前的想法是尝试多次使用 File.Move (C#) 进行重命名,如果它不起作用,则将其写入错误日志以便手动处理。

4

4 回答 4

18

一名飞机机械师和一名外科医生在酒吧见面。机械师说:“你知道,我们的工作基本上是一样的。我们把坏掉的东西拿出来,把新的、更好的零件放进去。” 外科医生说:“是的,但在进行维修时,您不必让飞机保持飞行!”

在应用程序运行时尝试通过移动文件来更新应用程序似乎与尝试修复飞行中的飞机一样危险。可能的?当然。灾难性崩溃的风险大大增加?是的。

如果您要更新的应用程序是托管应用程序,请考虑使用ClickOnce 部署。这样,下次有人运行该应用程序时,如果有新版本可用,它将被复制下来并自动安装。这比在应用程序仍在运行时试图弄乱它要安全和愉快得多。

于 2011-07-14T15:50:55.933 回答
10
  1. 不,这是不可接受的。不要这样做。这不是一个有效的部署机制。这应该是你或他的第一个线索:

    它有时会抛出该文件正在他的程序中使用的异常,但如果他尝试在循环中重命名它,它最终会成功。

    无论如何,它不会起作用。他的理论是完全错误的:

    使用该知识,他想重命名正在运行的 exe 并复制所述 exe 的新版本,这样任何运行 foo.exe 内存副本的人都可以,并且任何打开指向 foo.exe 的快捷方式的人都将获得一个新副本应用了更新。

    具体来说,内存中的副本不会因为同名而自动替换为新的可执行文件。首先允许您重命名可执行文件的原因是操作系统没有使用文件名来查找应用程序。原始可执行文件仍将被加载,并且在您显式卸载它并加载新的、修改后的可执行文件之前,它将一直被加载。

    请注意,即使是像 Chrome 和 Firefox 这样的现代网络浏览器,它们在后台拥有超棒的自动功能,没有人注意到它们的存在,更新程序仍然必须关闭并重新启动应用程序才能应用更新。

    不用担心在这里拍摄信使。您的客户和您的技术支持部门更有可能首先向您开枪。

  2. 见 1 号。

于 2011-07-14T15:21:11.293 回答
4

在我们的组织中,我们通过两个发布文件夹 EXE_A 和 EXE_B 解决了更新问题。我们还有一个名为 EXE 的发布文件夹,其中只有链接 ALL 指向用户运行应用程序的 EXE_A 或 EXE_B。

当我们发布程序的新版本时,我们将其发布到链接中未引用的文件夹中,然后更新链接(EXE)。这样,您就不会遇到用户持有应用程序/程序集的异常。此外,如果用户想要运行更新版本,他需要做的就是关闭/重新执行 EXE 文件夹中的链接。

于 2011-07-14T15:19:13.127 回答
1

如果您使用 Windows Vista/Server2k8 或更新版本,您可以使用mklink创建指向包含您的应用程序的文件夹的符号链接,并从“符号链接文件夹”中启动应用程序,然后在更新时创建一个新文件夹,例如“AppV2”和将 SymLink 更改为该文件夹,因此下次用户重新启动应用程序时,他会在没有注意到的情况下从新文件夹中启动它。

重命名打开的文件总是一个糟糕的选择!

但总的来说,无论如何我都会想到一个更好的部署策略,因为如果你需要使用这样的“黑客”,那总是一个混乱的局面。我不知道您的应用程序,但也许 ClickOnce 将是一个开始点,因为您可以将其配置为在每次启动时检查更新...

于 2011-07-14T15:32:09.600 回答