MsDelta.cs 2.5 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152
  1. using System;
  2. using System.ComponentModel;
  3. using System.Runtime.InteropServices;
  4. namespace MeloongCore {
  5. /// <summary>
  6. /// 使用 Windows MsDelta API 生成、应用增量补丁文件。
  7. /// </summary>
  8. public static class MsDelta {
  9. /// <summary>
  10. /// 生成增量补丁文件:比较 <paramref name="oldFilePath"/> 和 <paramref name="newFilePath"/>,将补丁写入 <paramref name="deltaFilePath"/>。
  11. /// </summary>
  12. public static void Create(string oldFilePath, string newFilePath, string deltaFilePath) {
  13. // fileTypeSet:https://learn.microsoft.com/en-us/previous-versions/bb417345(v=msdn.10)?redirectedfrom=MSDN#file-type-sets (15L: DELTA_FILE_TYPE_SET_EXECUTABLES)
  14. // 131072L: IgnoreFileSizeLimit, 32u: Crc32
  15. if (!CreateDelta(15L, 131072L, 0L,
  16. PathUtils.Shorten(oldFilePath), PathUtils.Shorten(newFilePath), null, null, new DeltaInput(), IntPtr.Zero, 32u, PathUtils.Shorten(deltaFilePath)))
  17. throw new Win32Exception();
  18. }
  19. /// <summary>
  20. /// 应用增量补丁文件:将 <paramref name="deltaFilePath"/> 补丁应用到 <paramref name="oldFilePath"/>,将结果写入 <paramref name="newFilePath"/>。
  21. /// </summary>
  22. public static void Apply(string oldFilePath, string deltaFilePath, string newFilePath) {
  23. // 1L: AllowLegacy
  24. if (!ApplyDelta(1L, PathUtils.Shorten(oldFilePath), PathUtils.Shorten(deltaFilePath), PathUtils.Shorten(newFilePath)))
  25. throw new Win32Exception();
  26. }
  27. [StructLayout(LayoutKind.Sequential)]
  28. private struct DeltaInput {
  29. public IntPtr Start;
  30. public IntPtr Size;
  31. [MarshalAs(UnmanagedType.Bool)] public bool Editable;
  32. }
  33. [DllImport("msdelta.dll", CharSet = CharSet.Unicode, SetLastError = true)]
  34. [return: MarshalAs(UnmanagedType.Bool)]
  35. private static extern bool CreateDelta(
  36. long fileTypeSet, long setFlags, long resetFlags,
  37. string sourceName, string targetName, string sourceOptionsName,
  38. string targetOptionsName, DeltaInput globalOptions,
  39. IntPtr targetFileTime, uint hashAlgId, string deltaName);
  40. [DllImport("msdelta.dll", CharSet = CharSet.Unicode, SetLastError = true)]
  41. [return: MarshalAs(UnmanagedType.Bool)]
  42. private static extern bool ApplyDelta(long applyFlags, string sourceName, string deltaName, string targetName);
  43. }
  44. }