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("'", @"\'");
    }
}