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

Mar*_*rek 3 windows deployment diff patch

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

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

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

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

  • 如果第一个问题是太难以解决或无法解决的可执行文件,我想至少学习是否有实现与串行版本简单的打补丁的解决方案 - 为了安装第5版,用户必须安装,以确保所有以前的版本部署的有效性.

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

有没有现成的解决方案来实现这一目标?

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

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

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

ang*_*son 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
Run Code Online (Sandbox Code Playgroud)

您将改为使用此方案:

      org v.2
     /      \
    +p1      +p4    <-- note, different patches now
   /          \
org v.1        org v.4
   \          /
    +p2      +p3
     \      /
      org v.3
Run Code Online (Sandbox Code Playgroud)

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

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

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

                                      +-- 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
Run Code Online (Sandbox Code Playgroud)

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

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