using System;
using System.ComponentModel;
using System.Runtime.InteropServices;
namespace MeloongCore {
///
/// 使用 Windows MsDelta API 生成、应用增量补丁文件。
///
public static class MsDelta {
///
/// 生成增量补丁文件:比较 和 ,将补丁写入 。
///
public static void Create(string oldFilePath, string newFilePath, string deltaFilePath) {
// fileTypeSet:https://learn.microsoft.com/en-us/previous-versions/bb417345(v=msdn.10)?redirectedfrom=MSDN#file-type-sets (15L: DELTA_FILE_TYPE_SET_EXECUTABLES)
// 131072L: IgnoreFileSizeLimit, 32u: Crc32
if (!CreateDelta(15L, 131072L, 0L,
PathUtils.Shorten(oldFilePath), PathUtils.Shorten(newFilePath), null, null, new DeltaInput(), IntPtr.Zero, 32u, PathUtils.Shorten(deltaFilePath)))
throw new Win32Exception();
}
///
/// 应用增量补丁文件:将 补丁应用到 ,将结果写入 。
///
public static void Apply(string oldFilePath, string deltaFilePath, string newFilePath) {
// 1L: AllowLegacy
if (!ApplyDelta(1L, PathUtils.Shorten(oldFilePath), PathUtils.Shorten(deltaFilePath), PathUtils.Shorten(newFilePath)))
throw new Win32Exception();
}
[StructLayout(LayoutKind.Sequential)]
private struct DeltaInput {
public IntPtr Start;
public IntPtr Size;
[MarshalAs(UnmanagedType.Bool)] public bool Editable;
}
[DllImport("msdelta.dll", CharSet = CharSet.Unicode, SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
private static extern bool CreateDelta(
long fileTypeSet, long setFlags, long resetFlags,
string sourceName, string targetName, string sourceOptionsName,
string targetOptionsName, DeltaInput globalOptions,
IntPtr targetFileTime, uint hashAlgId, string deltaName);
[DllImport("msdelta.dll", CharSet = CharSet.Unicode, SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
private static extern bool ApplyDelta(long applyFlags, string sourceName, string deltaName, string targetName);
}
}