如何使用修补程序更新应用程序文件?

时间:2010-04-11 08:32:08

标签: windows deployment diff patch

对任何自动更新解决方案感兴趣,例如ClickOnce或MS Updater Block。对于任何感觉有人问为什么不这样做的人:我已经在使用这些并且它们没有任何问题,我只想了解任何有效的替代方案。

我想发布补丁 =小差异,这些差异将修改具有最小可能增量的部署的现有文件。不仅需要修补代码,还需要修补资源文件。修补正在运行的代码可以通过维护部署的两个单独的同步副本来完成(不需要动态更改正在运行的可执行文件)。

应用程序本身可以部署xcopy(以避免MSI自动更正已修改的文件或破坏ClickOnce签名)。

  • 我想学习如何处理不同版本的补丁(例如,有一个补丁发布修复了一个错误,后来另一个补丁修复了另一个错误(在同一个文件中) - 用户可能有任何组合这些和第三个补丁 - 在文本文件中,这可能很容易实现,但可执行文件怎么样?(本机Win32代码与.NET,有什么不同?)

  • 如果第一个问题难以解决或无法解决可执行文件问题,我想至少了解是否有一个解决方案实现了对序列修订的简单修补 - 为了安装修订版5,用户必须拥有安装以前的所有修订版以确保部署的有效性。

  • 补丁可以作为网站上的可下载文件发布 - 无需直接从正在运行的应用程序中自动修补功能。

是否有任何现有的解决方案可以实现这一目标?

注意:关于SO的一些问题可能看起来像重复,但没有一个问题有好的答案。

这个问题是关于Windows平台的,最好是.NET。

到目前为止,wyUpdate似乎最适合这个问题。仍然对替代品感兴趣。

1 个答案:

答案 0 :(得分:6)

您将无法创建一个可应用于该程序的多个版本的二进制修补程序,因此无法实现以下方案:

      org+p1
     /      \
    + p1     +p2    <-- note, p2 is the same patch both places
   /          \
original       org+p1+p2
   \          /
    + p2     +p1    <-- ie. the p2 on this line is the same as the one above
     \      /
      org+p2

您将改为使用此方案:

      org v.2
     /      \
    +p1      +p4    <-- note, different patches now
   /          \
org v.1        org v.4
   \          /
    +p2      +p3
     \      /
      org v.3

如果您希望允许用户选择他们想要应用的修补程序,您应该很容易看到它变得多么复杂。是的,毕竟这可以通过文本文件来完成,这就是分支和合并如何与大多数源代码控制工具一起工作,但它们的工作原理是您可以插入和删除文件中的内容而不会影响文件的其余部分,不适用于可执行文件。

注意:特殊情况是修复替换字节,但不插入或删除文件中的任何内容。只要多个此类修复不重叠,就可以选择要应用的修复程序。但是,这样的补丁是非常罕见的。

正如您在问题中暗示的那样,您应该使用串行时间轴,可能使用现有版本的单个修补程序,因此您可能会改为:

                                      +-- most up to date version
                                      |            
                                      v
org v.1         org v.3             org v.4
   \           /       \           /
    +p1       +p2       +p3       +p4
     \       /           \       /
      org v.2             org v.4
       \
        +p1.1
         \
          org v.2 hotfix 1

至于实际代码,我有一个diff / patch实现,但它可能远非最佳。它目前需要很多时间来生成任何大小文件的补丁文件。补丁相当小,但我敢说其他算法会产生更好的补丁。使用bsdiff and bspatch进行的样本测试会产生较小的补丁。

但是,如果你想玩它,代码是here。它是一个更大的类库的一部分,我不记得你需要编译多少它(库的其余部分)只是编译二进制补丁类,但它就在那里。您要使用的类是Delta2类。