如何判斷虛擬磁盤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 編輯過