编程方式制作增量补丁
2024-03-17 17:33:41

微软提供了两套API来制作增量补丁,PatchAPI和MSDelta
PatchAPI支持XP,效率高但文件会比MSDelta大,属于第一代增量压缩接口,不建议使用。
MSDelta不支持XP系统,补丁文件更小,兼容PatchAPI的补丁,微软的补丁包用了此接口。

PatchAPI

创建补丁文件通过 CreatePatchFile 函数,它是高级的API,制作一对一的升级补丁

1
2
3
4
#include <PatchApi.h>
#pragma comment(lib, "mspatchc")

BOOL bSuccess = ::CreatePatchFileA("D:\\v1.exe", "D:\\v2.exe", "D:\\Patch.dat", PATCH_OPTION_USE_BEST, nullptr);

补丁文件由文件头和数据组成,提取文件头可以用 ExtractPatchHeaderToFile 函数

1
BOOL bSuccess = ExtractPatchHeaderToFileA("D:\\Patch.dat", "D:\\header.dat");

文件头数据由”PA19”标记开始

打补丁通过 ApplyPatchToFile 函数,它是由mspatcha.dll提供的

1
2
3
4
#include <PatchApi.h>
#pragma comment(lib, "mspatcha")

BOOL bSuccess = ::ApplyPatchToFileA("D:\\Patch.dat", "D:\\v1.exe", "D:\\v2.exe", 0);

如果需要验证补丁而不应用,可以用 TestApplyPatchToFile 函数。
从多个源文件制作补丁可以用 CreatePatchFileEx 函数

1
2
3
4
5
6
7
8
#include <PatchApi.h>
#pragma comment(lib, "mspatchc")

PATCH_OLD_FILE_INFO_A src[2]{ 0 };
src[0].OldFileName = "D:\\v1.exe";
src[1].OldFileName = "D:\\v2.exe";

BOOL bSuccess = CreatePatchFileExA(_countof(src), src, "D:\\v3.exe", "D:\\Patch.dat", 0, nullptr, nullptr, nullptr);

这样无论是v1还是v2都能升级到v3

MSDelta

PatchAPI的升级版本,补丁文件的头为”PA30”。
制作补丁使用 CreateDelta 函数

1
2
3
4
#include <msdelta.h>
#pragma comment(lib, "msdelta")

BOOL bSuccess = CreateDeltaA(DELTA_FILE_TYPE_SET_EXECUTABLES_LATEST, DELTA_FLAG_NONE, DELTA_FLAG_NONE, "D:\\v1.exe", "D:\\v2.exe", nullptr, nullptr, { 0 }, nullptr, 0, "D:\\Patch.dat");

获取增量补丁信息:GetDeltaInfo
应用增量补丁:ApplyDelta
从文档上看,并没有提供从多个源文件制作补丁的方法

参考

Delta Compression Application Programming Interfaces

PatchAPI

https://github.com/hfiref0x/SXSEXP

https://forum.xda-developers.com/windows-10-mobile/decompress-manifests-files-winsxs-folder-t3367399