如何判断虚拟磁盘VHDX文件是否已经被挂载,挂载到了哪一个盘符,并且当前是挂载为只读模式还是可读写模式呢?以下是用于检测VHDX挂载状态和属性的完整C#实现方案:
using System;
using System.IO;
using System.Management;
using System.Diagnostics;
using System.Text;
class VhdxStatusChecker
{
public static (bool isMounted, string drives, bool isReadOnly) CheckVhdxStatus(string vhdxPath)
{
var normalizedPath = Path.GetFullPath(vhdxPath).ToLower();
using (var searcher = new ManagementObjectSearcher("SELECT * FROM Win32_DiskDrive"))
{
foreach (ManagementObject disk in searcher.Get())
{
if (disk["MediaType"]?.ToString() != "Microsoft Virtual Disk")
continue;
var diskPath = GetVhdxPathFromDisk(disk);
if (diskPath == null) continue;
if (Path.GetFullPath(diskPath).ToLower() != normalizedPath)
continue;
var drives = GetMountedDrives(disk);
var isReadOnly = CheckReadOnlyStatus(diskPath);
return (true, drives, isReadOnly);
}
}
return (false, null, false);
}
private static string GetVhdxPathFromDisk(ManagementObject disk)
{
if (disk["FileName"] is string fileName && fileName.EndsWith(".vhdx", StringComparison.OrdinalIgnoreCase))
return fileName;
try
{
using (var p = new ManagementObject($"Win32_DiskDrive.DeviceID='{disk["DeviceID"]}'"))
{
p.Scope = new ManagementScope(@"\\.\root\Microsoft\Windows\Storage");
return p["FileName"]?.ToString();
}
}
catch { }
return null;
}
private static string GetMountedDrives(ManagementObject disk)
{
var sb = new StringBuilder();
var query = $"ASSOCIATORS OF {{Win32_DiskDrive.DeviceID='{EscapeWmiPath(disk["DeviceID"].ToString())}'}} " +
"WHERE AssocClass = Win32_DiskDriveToDiskPartition";
using (var partitions = new ManagementObjectSearcher(query).Get())
{
foreach (ManagementObject partition in partitions)
{
var driveQuery = $"ASSOCIATORS OF {{Win32_DiskPartition.DeviceID='{EscapeWmiPath(partition["DeviceID"].ToString())}'}} " +
"WHERE AssocClass = Win32_LogicalDiskToPartition";
using (var drives = new ManagementObjectSearcher(driveQuery).Get())
{
foreach (ManagementObject drive in drives)
{
if (drive["DeviceID"] != null)
sb.Append($"{drive["DeviceID"]} ");
}
}
}
}
return sb.ToString().Trim();
}
private static bool CheckReadOnlyStatus(string vhdxPath)
{
var output = ExecuteDiskPartCommand($@"
select vdisk file=""{vhdxPath}""
detail vdisk
exit
");
var patterns = new[] {
new { Key = "Read-only", Yes = "Yes", No = "No" },
new { Key = "只读", Yes = "是", No = "否" },
new { Key = "Schreibgeschützt", Yes = "Ja", No = "Nein" }
};
foreach (var pattern in patterns)
{
var start = output.IndexOf(pattern.Key);
if (start == -1) continue;
var valueStart = output.IndexOf(':', start) + 1;
var valueEnd = output.IndexOf('\n', valueStart);
var value = output.Substring(valueStart, valueEnd - valueStart).Trim();
return value.Equals(pattern.Yes, StringComparison.OrdinalIgnoreCase);
}
return false;
}
private static string ExecuteDiskPartCommand(string script)
{
var tempFile = Path.GetTempFileName();
File.WriteAllText(tempFile, script, Encoding.Unicode);
try
{
var psi = new ProcessStartInfo("diskpart")
{
Arguments = $"/s \"{tempFile}\"",
RedirectStandardOutput = true,
UseShellExecute = false,
CreateNoWindow = true,
StandardOutputEncoding = Encoding.Unicode
};
using (var process = Process.Start(psi))
{
var output = process.StandardOutput.ReadToEnd();
process.WaitForExit(5000);
return output;
}
}
finally
{
File.Delete(tempFile);
}
}
private static string EscapeWmiPath(string path)
{
return path.Replace(@"\", @"\\").Replace("'", @"\'");
}
}
使用示例:
var (isMounted, drives, isReadOnly) = VhdxStatusChecker.CheckVhdxStatus(@"D:\Backup.vhdx");
Console.WriteLine($"已挂载: {isMounted}");
Console.WriteLine($"盘符: {drives ?? "无"}");
Console.WriteLine($"只读模式: {isReadOnly}");
方案特性:
1、多语言兼容:
支持检测英语、中文、德语系统的只读状态
自动识别系统语言输出格式
使用Unicode编码处理特殊字符
2、双重检测机制:
通过WMI获取基础磁盘信息
通过diskpart验证详细属性
3、兼容性处理:
4、错误防御:
自动转义WMI查询路径
处理磁盘分区的多种情况
超时机制防止进程挂起
实现原理:
1、WMI查询:
通过Win32_DiskDrive定位虚拟磁盘
使用关联查询获取挂载盘符
2、diskpart检测:
执行detail vdisk获取详细信息
多语言关键字匹配检测只读状态
3、路径标准化:
统一转换为全路径和小写格式
处理不同来源的路径格式差异
注意事项:
1、运行权限:
2、异常处理:
try {
var result = VhdxStatusChecker.CheckVhdxStatus(path);
}
catch (Exception ex) {
Console.WriteLine($"检测失败: {ex.Message}");
}
3、性能优化:
该方案通过结合WMI和diskpart的优势,实现了可靠的VHDX状态检测,适用于需要高可靠性保障的备份系统。
相关教程:
C#零成本实现云服务器上Windows系统数据库自动备份并防止备份文件被勒索病毒破坏[
20]
http://31161.oa22.cn
该文章在 2025/5/16 11:03:58 编辑过