C#ユーティリティ:DriveUtil.cs – ドライブの種類を判定するユーティリティ

コンピュータ

Utilities\DriveUtil.cs

// ドライブの種類を判定するユーティリティ
using System;
using System.Collections.Concurrent;
using System.IO;
using System.Management;

namespace Maywork.Utilities;

public enum DriveKind
{
    Unknown,
    SSD,
    HDD,
    Network,
    Removable
}

public static class DriveUtil
{
    private static readonly ConcurrentDictionary<string, DriveKind> _cache = new();

    public static DriveKind GetDriveKind(string path)
    {
        var root = Path.GetPathRoot(path);
        if (string.IsNullOrWhiteSpace(root))
            return DriveKind.Unknown;

        root = root.TrimEnd('\\');

        return _cache.GetOrAdd(root, DetectDriveKindInternal);
    }


    private static DriveKind DetectPhysicalDriveKind(string driveLetter)
    {
        try
        {
            // ① LogicalDisk → Partition
            using var partitionSearcher = new ManagementObjectSearcher(
                $"ASSOCIATORS OF {{Win32_LogicalDisk.DeviceID='{driveLetter}'}} WHERE AssocClass=Win32_LogicalDiskToPartition");

            foreach (ManagementObject partition in partitionSearcher.Get())
            {
                // ② Partition → DiskDrive
                using var diskSearcher = new ManagementObjectSearcher(
                    $"ASSOCIATORS OF {{Win32_DiskPartition.DeviceID='{partition["DeviceID"]}'}} WHERE AssocClass=Win32_DiskDriveToDiskPartition");

                foreach (ManagementObject disk in diskSearcher.Get())
                {
                    var index = disk["Index"];
                    if (index == null)
                        continue;

                    // ③ MSFT_PhysicalDisk で MediaType取得
                    using var physicalSearcher = new ManagementObjectSearcher(
                        @"ROOT\Microsoft\Windows\Storage",
                        $"SELECT MediaType FROM MSFT_PhysicalDisk WHERE DeviceId={index}");

                    foreach (ManagementObject physical in physicalSearcher.Get())
                    {
                        var mediaType = Convert.ToUInt16(physical["MediaType"]);

                        return mediaType switch
                        {
                            4 => DriveKind.SSD,
                            3 => DriveKind.HDD,
                            _ => DriveKind.HDD
                        };
                    }
                }
            }
        }
        catch
        {
        }

        return DriveKind.HDD;
    }

    private static DriveKind DetectDriveKindInternal(string driveLetter)
    {
        var driveInfo = new DriveInfo(driveLetter);

        if (driveInfo.DriveType == DriveType.Network)
            return DriveKind.Network;

        if (driveInfo.DriveType == DriveType.Removable)
            return DriveKind.Removable;

        return DetectPhysicalDriveKind(driveLetter);
    }

    public static string DriveKindToString(DriveKind kind)
    {
        return kind switch
        {
            DriveKind.SSD => "SSD",
            DriveKind.HDD => "HDD",
            DriveKind.Network => "NAS",
            _ => "Unknown"
        };
    }
}

/*
 // 準備
dotnet add package System.Management
 // 使用例
var kind = DriveUtilities.GetDriveKind(@"D:\Images\a.png");

switch (kind)
{
    case DriveKind.SSD:
        Console.WriteLine("SSD");
        break;

    case DriveKind.HDD:
        Console.WriteLine("HDD");
        break;

    case DriveKind.Network:
        Console.WriteLine("NAS");
        break;
}
*/
Download

コメント