LOGO OA教程 ERP教程 模切知識交流 PMS教程 CRM教程 開發文檔 其他文檔  
 
網站管理員

【C#】如何判斷虛擬磁盤VHDX文件是否已經被掛載,掛載到了哪一個盤符,并且當前是掛載為只讀模式還是可讀寫模式

admin
2025年5月16日 11:1 本文熱度 59

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


                // 獲取VHDX文件路徑

                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);

    }


    // 獲取VHDX文件路徑(兼容不同Windows版本)

    private static string GetVhdxPathFromDisk(ManagementObject disk)

    {

        // 方法1:通過FileName屬性獲取

        if (disk["FileName"] is string fileName && fileName.EndsWith(".vhdx", StringComparison.OrdinalIgnoreCase))

            return fileName;


        // 方法2:通過WMI擴展屬性獲取(需要Windows 8+)

        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; // 默認返回可寫狀態

    }


    // 執行diskpart命令并獲取輸出

    private static string ExecuteDiskPartCommand(string script)

    {

        var tempFile = Path.GetTempFileName();

        File.WriteAllText(tempFile, script, Encoding.Unicode); // 必須使用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);

        }

    }


    // WMI路徑轉義工具方法

    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、兼容性處理:

  • 支持Windows 7及更高版本

  • 兼容傳統Win32接口和新的Storage命名空間

4、錯誤防御:

  • 自動轉義WMI查詢路徑

  • 處理磁盤分區的多種情況

  • 超時機制防止進程掛起

實現原理:

1、WMI查詢:

  • 通過Win32_DiskDrive定位虛擬磁盤

  • 使用關聯查詢獲取掛載盤符

2、diskpart檢測:

  • 執行detail vdisk獲取詳細信息

  • 多語言關鍵字匹配檢測只讀狀態

3、路徑標準化:

  • 統一轉換為全路徑和小寫格式

  • 處理不同來源的路徑格式差異

注意事項:

1、運行權限:

// 需要以管理員身份運行程序

// 在項目文件中添加:

// <ApplicationManifest>app.manifest</ApplicationManifest>

// 并啟用requireAdministrator

2、異常處理:

try {

    var result = VhdxStatusChecker.CheckVhdxStatus(path);

}

catch (Exception ex) {

    Console.WriteLine($"檢測失敗: {ex.Message}");

}

3、性能優化:

// 對于頻繁檢測的場景,可以緩存ManagementObjectSearcher實例

// 但需要注意及時釋放資源

該方案通過結合WMI和diskpart的優勢,實現了可靠的VHDX狀態檢測,適用于需要高可靠性保障的備份系統。


相關教程:

C#零成本實現云服務器上Windows系統數據庫自動備份并防止備份文件被勒索病毒破壞[20]
  http://31161.oa22.cn


該文章在 2025/5/16 11:03:58 編輯過
關鍵字查詢
相關文章
正在查詢...
點晴ERP是一款針對中小制造業的專業生產管理軟件系統,系統成熟度和易用性得到了國內大量中小企業的青睞。
點晴PMS碼頭管理系統主要針對港口碼頭集裝箱與散貨日常運作、調度、堆場、車隊、財務費用、相關報表等業務管理,結合碼頭的業務特點,圍繞調度、堆場作業而開發的。集技術的先進性、管理的有效性于一體,是物流碼頭及其他港口類企業的高效ERP管理信息系統。
點晴WMS倉儲管理系統提供了貨物產品管理,銷售管理,采購管理,倉儲管理,倉庫管理,保質期管理,貨位管理,庫位管理,生產管理,WMS管理系統,標簽打印,條形碼,二維碼管理,批號管理軟件。
點晴免費OA是一款軟件和通用服務都免費,不限功能、不限時間、不限用戶的免費OA協同辦公管理系統。
Copyright 2010-2025 ClickSun All Rights Reserved

黄频国产免费高清视频,久久不卡精品中文字幕一区,激情五月天AV电影在线观看,欧美国产韩国日本一区二区
午夜成人亚洲理论片在线观看 | 中文字幕HD天堂字幕乱码五月 | 亚洲午夜福利片 | 自产国产一区二区 | 香港三日本三级少妇三99 | 亚洲欧洲精品一区二区三区 |