using System;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Security.AccessControl;
using System.Security.Principal;
class VhdxBackupManager
{
const string VhdxPath = @"D:\Backup.vhdx";
const string AdminAccount = "Administrators";
static char _currentDriveLetter = 'E'; // 默认起始盘符
public static void ExecuteSafeBackup()
{
try
{
// 0. 确保VHDX文件存在
if (!File.Exists(VhdxPath))
{
CreateNewVhdx();
SetVhdxPermissions();
}
// 1. 寻找可用盘符
char driveLetter = FindAvailableDriveLetter();
// 2. 挂载可读写VHDX
MountVhdx(driveLetter, readOnly: false);
// 3. 执行备份操作
File.Copy("C:\\Data\\important.txt", $"{driveLetter}:\\important.txt", true);
// 4. 卸载并重新挂载为只读
DismountVhdx(driveLetter);
MountVhdx(driveLetter, readOnly: true);
}
catch (Exception ex)
{
DismountVhdx(_currentDriveLetter); // 尝试卸载当前盘符
Console.WriteLine($"Error: {ex.Message}");
}
}
// 动态查找可用盘符(从E到Z)
private static char FindAvailableDriveLetter()
{
var usedDrives = DriveInfo.GetDrives()
.Select(d => d.Name[0])
.ToList();
for (char c = 'E'; c <= 'Z'; c++)
{
if (!usedDrives.Contains(c))
{
_currentDriveLetter = c;
return c;
}
}
throw new InvalidOperationException("没有可用的驱动器盘符");
}
// 挂载虚拟磁盘方法
private static void MountVhdx(char driveLetter, bool readOnly)
{
var script = $@"
select vdisk file={VhdxPath}
attach vdisk {(readOnly ? "readonly" : "")}
assign letter={driveLetter}
exit
";
ExecuteDiskPart(script);
// 验证挂载是否成功
if (!Directory.Exists($"{driveLetter}:\\"))
{
throw new Exception($"挂载到 {driveLetter}: 失败");
}
}
// 卸载虚拟磁盘方法
private static void DismountVhdx(char driveLetter)
{
var script = $@"
select vdisk file={VhdxPath}
detach vdisk
exit
";
ExecuteDiskPart(script);
}
// 原有权限设置方法保持不变
private static void SetVhdxPermissions()
{
var fileInfo = new FileInfo(VhdxPath);
FileSecurity fSecurity = fileInfo.GetAccessControl();
// 禁用继承并清除所有现有权限
fSecurity.SetAccessRuleProtection(true, false);
AuthorizationRuleCollection rules = fSecurity.GetAccessRules(true, true, typeof(NTAccount));
foreach (FileSystemAccessRule rule in rules)
{
fSecurity.RemoveAccessRule(rule);
}
// 添加SYSTEM完全控制(挂载操作需要)
fSecurity.AddAccessRule(new FileSystemAccessRule(
new SecurityIdentifier(WellKnownSidType.LocalSystemSid, null),
FileSystemRights.FullControl,
AccessControlType.Allow));
// 添加管理员组只读权限
fSecurity.AddAccessRule(new FileSystemAccessRule(
new NTAccount(AdminAccount),
FileSystemRights.Read | FileSystemRights.ExecuteFile,
InheritanceFlags.None,
PropagationFlags.None,
AccessControlType.Allow));
// 禁止Everyone写入
fSecurity.AddAccessRule(new FileSystemAccessRule(
new SecurityIdentifier(WellKnownSidType.WorldSid, null),
FileSystemRights.Write,
AccessControlType.Deny));
fileInfo.SetAccessControl(fSecurity);
}
private static void CreateNewVhdx()
{
var script = $@"
create vdisk file={VhdxPath} maximum=10240 type=expandable
select vdisk file={VhdxPath}
attach vdisk
create partition primary
format quick fs=ntfs label=BackupDrive
detach vdisk
exit
";
ExecuteDiskPart(script);
}
private static void ExecuteDiskPart(string script)
{
var tempFile = Path.GetTempFileName();
File.WriteAllText(tempFile, script);
using (var process = new Process())
{
process.StartInfo = new ProcessStartInfo
{
FileName = "diskpart",
Arguments = $"/s {tempFile}",
UseShellExecute = false,
CreateNoWindow = true
};
process.Start();
process.WaitForExit(15000);
if (process.ExitCode != 0)
{
File.Delete(tempFile);
throw new Exception("diskpart执行失败,返回码:" + process.ExitCode);
}
}
File.Delete(tempFile);
}
}