125 lines
5.9 KiB
C#
125 lines
5.9 KiB
C#
using System.Text.Json;
|
|
using WindowsToolbox.Core;
|
|
using WindowsToolbox.Infrastructure;
|
|
|
|
var failures = new List<string>();
|
|
|
|
Check(ToolboxCommandDispatcher.RequiresElevation(ToolboxCommandKind.DisableWindowsUpdate),
|
|
"关闭更新必须提权");
|
|
Check(!ToolboxCommandDispatcher.RequiresElevation(ToolboxCommandKind.ArchiveDesktop),
|
|
"桌面归档不应要求提权");
|
|
|
|
var command = new ToolboxCommand
|
|
{
|
|
Id = "verification",
|
|
Kind = ToolboxCommandKind.PauseWindowsUpdate,
|
|
Arguments = new Dictionary<string, string> { ["days"] = "35" }
|
|
};
|
|
var roundTrip = JsonSerializer.Deserialize<ToolboxCommand>(
|
|
JsonSerializer.Serialize(command, JsonDefaults.Options), JsonDefaults.Options);
|
|
Check(roundTrip?.Kind == ToolboxCommandKind.PauseWindowsUpdate, "命令 JSON 往返失败");
|
|
Check(roundTrip?.Arguments.GetValueOrDefault("days") == "35", "命令参数 JSON 往返失败");
|
|
|
|
var activation = new ActivationService(new RegistryStore(), new SnapshotStore(), new ProcessRunner());
|
|
var catalog = activation.LoadCatalog();
|
|
Check(catalog.Any(x => x.EditionId == "Professional" && x.ProductKey == "W269N-WFGWX-YVC9B-4J6C9-T83GX"),
|
|
"KMS 专业版目录缺失");
|
|
Check(catalog.Any(x => x.EditionId == "Core" && !x.Supported),
|
|
"家庭版应明确标记为不支持 KMS");
|
|
Check(catalog.Where(x => x.Supported).All(x => x.ProductKey.Length == 29),
|
|
"KMS 客户端密钥格式错误");
|
|
|
|
var temporaryRoot = Path.Combine(Path.GetTempPath(), "WindowsToolbox-Verification-" + Guid.NewGuid().ToString("N"));
|
|
try
|
|
{
|
|
var testDesktop = Path.Combine(temporaryRoot, "Desktop");
|
|
var testDestination = Path.Combine(temporaryRoot, "Archive");
|
|
Directory.CreateDirectory(testDesktop);
|
|
File.WriteAllText(Path.Combine(testDesktop, "report.txt"), "first");
|
|
File.WriteAllText(Path.Combine(testDesktop, "keep.lnk"), "shortcut");
|
|
var projectFolder = Path.Combine(testDesktop, "Project");
|
|
Directory.CreateDirectory(projectFolder);
|
|
File.WriteAllText(Path.Combine(projectFolder, "first.txt"), "folder-first");
|
|
var systemFolder = Path.Combine(testDesktop, "SystemFolder");
|
|
Directory.CreateDirectory(systemFolder);
|
|
File.SetAttributes(systemFolder, File.GetAttributes(systemFolder) | FileAttributes.System);
|
|
|
|
var desktopService = new DesktopArchiveService(
|
|
new TaskSchedulerService(),
|
|
() => testDesktop,
|
|
Path.Combine(temporaryRoot, "Data"));
|
|
var archiveCommand = new ToolboxCommand
|
|
{
|
|
Id = Guid.NewGuid().ToString("N"),
|
|
Kind = ToolboxCommandKind.ArchiveDesktop,
|
|
Arguments = new Dictionary<string, string>
|
|
{
|
|
["profile"] = "verification",
|
|
["destination"] = testDestination
|
|
}
|
|
};
|
|
var firstArchive = await desktopService.ArchiveAsync(archiveCommand);
|
|
var dateFolder = Path.Combine(testDestination, DateTime.Now.ToString("yyyy-MM-dd"));
|
|
Check(firstArchive.Success, "第一次桌面归档失败");
|
|
Check(File.Exists(Path.Combine(dateFolder, "report.txt")), "普通文件没有归档");
|
|
Check(File.Exists(Path.Combine(testDesktop, "keep.lnk")), "快捷方式不应被移动");
|
|
Check(Directory.Exists(Path.Combine(dateFolder, "Project")), "普通文件夹没有归档");
|
|
Check(Directory.Exists(systemFolder), "系统文件夹不应被移动");
|
|
|
|
await Task.Delay(5);
|
|
File.WriteAllText(Path.Combine(testDesktop, "report.txt"), "second");
|
|
Directory.CreateDirectory(projectFolder);
|
|
File.WriteAllText(Path.Combine(projectFolder, "second.txt"), "folder-second");
|
|
var secondArchive = await desktopService.ArchiveAsync(archiveCommand with { Id = Guid.NewGuid().ToString("N") });
|
|
Check(secondArchive.Success, "第二次桌面归档失败");
|
|
Check(File.Exists(Path.Combine(dateFolder, "report (1).txt")), "同一天同名文件没有自动编号");
|
|
Check(Directory.Exists(Path.Combine(dateFolder, "Project (1)")), "同一天同名文件夹没有自动编号");
|
|
|
|
await Task.Delay(5);
|
|
Directory.CreateDirectory(projectFolder);
|
|
File.WriteAllText(Path.Combine(projectFolder, "third.txt"), "folder-third");
|
|
var thirdArchive = await desktopService.ArchiveAsync(archiveCommand with { Id = Guid.NewGuid().ToString("N") });
|
|
Check(thirdArchive.Success, "第三次桌面归档失败");
|
|
Check(Directory.Exists(Path.Combine(dateFolder, "Project (2)")), "多次同名文件夹没有继续自动编号");
|
|
|
|
var undo = await desktopService.UndoLatestAsync(new ToolboxCommand
|
|
{
|
|
Id = Guid.NewGuid().ToString("N"),
|
|
Kind = ToolboxCommandKind.UndoDesktopArchive
|
|
});
|
|
Check(undo.Success, "撤销最近桌面归档失败");
|
|
Check(File.Exists(Path.Combine(testDesktop, "Project", "third.txt")), "撤销没有恢复最近一次文件夹");
|
|
Check(File.Exists(Path.Combine(dateFolder, "report.txt")), "撤销最近一次不应影响更早归档");
|
|
Check(File.Exists(Path.Combine(dateFolder, "report (1).txt")), "撤销文件夹归档不应影响更早归档文件");
|
|
Check(Directory.Exists(Path.Combine(dateFolder, "Project")), "撤销最近一次不应影响更早归档文件夹");
|
|
Check(Directory.Exists(Path.Combine(dateFolder, "Project (1)")), "撤销最近一次不应影响第二次归档文件夹");
|
|
}
|
|
finally
|
|
{
|
|
if (Directory.Exists(temporaryRoot))
|
|
{
|
|
foreach (var path in Directory.EnumerateFileSystemEntries(temporaryRoot, "*", SearchOption.AllDirectories))
|
|
{
|
|
try { File.SetAttributes(path, FileAttributes.Normal); } catch { }
|
|
}
|
|
Directory.Delete(temporaryRoot, recursive: true);
|
|
}
|
|
}
|
|
|
|
if (failures.Count > 0)
|
|
{
|
|
Console.Error.WriteLine(string.Join(Environment.NewLine, failures));
|
|
return 1;
|
|
}
|
|
|
|
Console.WriteLine($"验证通过:{catalog.Count} 个 KMS 版本条目;命令模型、权限边界、文件与文件夹归档、系统项排除、同名处理和撤销正常。");
|
|
return 0;
|
|
|
|
void Check(bool condition, string message)
|
|
{
|
|
if (!condition)
|
|
{
|
|
failures.Add("失败: " + message);
|
|
}
|
|
}
|