首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >如何从USB驱动器名中获取磁盘索引?请考虑带有分区和不带分区的USB。

如何从USB驱动器名中获取磁盘索引?请考虑带有分区和不带分区的USB。
EN

Stack Overflow用户
提问于 2022-10-31 10:12:06
回答 2查看 104关注 0票数 1

我想要清理usb使用磁盘从C#。我已经写了下面的代码在C#得到所有连接的USB。在cmd命令下,我遍历所有usb并使用磁盘清除每个usb。

代码语言:javascript
运行
复制
  diskpart
   list disk
   select disk <0/1/2>
   clean

我想得到磁盘号码<0/1/2>从驱动器名称,以便我可以清理每个usb一个接一个。

代码语言:javascript
运行
复制
foreach (DriveInfo drive in DriveInfo.GetDrives())
                {
                    if (drive.IsReady == true)
                    {
                        if (drive.DriveType == DriveType.Removable)
                        {
                          string usbName = drive.Name;
                        }
                     }
}

EN

回答 2

Stack Overflow用户

发布于 2022-11-01 03:32:42

以下说明如何使用ManagementObjectSearcherManagementObject检索可移动USB驱动器列表

Windows Forms App (.NET Framework) 创建项目

添加引用 (System.Management)

VS 2022年

  • 单击项目
  • 选择添加引用.
  • 单击程序集
  • 检查System.Management
  • 单击OK

使用指令添加

  • using System.IO;
  • using System.Management;
  • using System.Diagnostics;

创建一个类(名称: LogicalDiskInfo)

代码语言:javascript
运行
复制
public class LogicalDiskInfo : IComparable<LogicalDiskInfo>
{
    public string Description { get; set; }
    public string DeviceID { get; set; }
    public uint DiskIndex { get; set; }
    public uint DriveType { get; set; }
    public string FileSystem { get; set; }
    public bool IsRemovable { get; set; } = false;
    public string Name { get; set; }
    public uint PartitionIndex { get; set; }
    public uint PartitionNumber { get; set; }
    public UInt64 Size { get; set; }

    public int CompareTo(LogicalDiskInfo other)
    {
        if (String.Compare(this.Name, other.Name) == 0)
            return 0;
        else if (String.Compare(this.Name, other.Name) < 0)
            return -1;
        else
            return 1;
    }
}

创建一个类(名称: LogicalDisk)

代码语言:javascript
运行
复制
public class LogicalDisk
{
    public List<LogicalDiskInfo> LogicalDiskInfos = new List<LogicalDiskInfo>();
}

创建一个类(名称: DiskDriveInfo)

代码语言:javascript
运行
复制
public class DiskDriveInfo : IComparable<DiskDriveInfo>
{
    public string Caption { get; set; } = string.Empty;
    public string DeviceID { get; set; } = string.Empty;
    public List<LogicalDiskInfo> LogicalDisks { get; set; } = new List<LogicalDiskInfo>();
    public UInt32 DiskIndex { get; set; } = 0;
    public string InterfaceType { get; set; } = string.Empty;
    public bool IsRemovable { get; set; } = false;
    public string MediaType { get; set; }
    public string Model { get; set; } = string.Empty;
    public string Name { get; set; } = string.Empty;
    public UInt32 Partitions { get; set; } = 0;
    public string PnpDeviceID { get; set; } = string.Empty;
    public UInt64 Size { get; set; } = 0;
    public string Status { get; set; } = string.Empty;

    public int CompareTo(DiskDriveInfo other)
    {
        if (this.DiskIndex == other.DiskIndex)
            return 0;
        else if (this.DiskIndex < other.DiskIndex)
            return -1;
        else
            return 1;
    }
}

GetUSBRemovableDiskDriveInfo:

备注:在Windows10中,可以在一个USB驱动器上创建多个分区。有关更多信息,请参见这里。因此,在同一个物理磁盘驱动器上可能存在多个驱动器号。下面的代码适用于具有单个分区或多个分区的USB驱动器。

代码语言:javascript
运行
复制
private List<DiskDriveInfo> GetUSBRemovableDiskDriveInfo()
{
    SortedDictionary<uint, DiskDriveInfo> diskDict = new SortedDictionary<uint, DiskDriveInfo>();

    List<DiskDriveInfo> driveInfos = new List<DiskDriveInfo>();

    //MediaType: 'Removable Media'
    using (ManagementObjectSearcher searcherDiskDrive = new ManagementObjectSearcher("SELECT Caption, DeviceID, Index, InterfaceType, MediaType, Model, Name, Partitions, PNPDeviceID, Size, Status FROM Win32_DiskDrive WHERE InterfaceType='USB' and MediaType='Removable Media'"))
    {
        foreach (ManagementObject objDiskDrive in searcherDiskDrive.Get())
        {
            if (objDiskDrive == null)
                continue;

            //create new instance
            DiskDriveInfo ddInfo = new DiskDriveInfo();

            //set value
            uint diskIndex = Convert.ToUInt32(objDiskDrive["Index"]);

            ddInfo.Caption = objDiskDrive["Caption"]?.ToString();
            ddInfo.DeviceID = objDiskDrive["DeviceID"]?.ToString();
            ddInfo.DiskIndex = diskIndex;
            ddInfo.InterfaceType = objDiskDrive["InterfaceType"]?.ToString();
            ddInfo.MediaType = objDiskDrive["MediaType"]?.ToString();
            ddInfo.Model = objDiskDrive["Model"]?.ToString();
            ddInfo.Name = objDiskDrive["Name"]?.ToString();
            ddInfo.Partitions = Convert.ToUInt32(objDiskDrive["Partitions"]);
            ddInfo.PnpDeviceID = objDiskDrive["PnpDeviceID"]?.ToString();
            ddInfo.Size = Convert.ToUInt64(objDiskDrive["Size"]);
            ddInfo.Status = objDiskDrive["Status"]?.ToString();

            if (ddInfo.MediaType == "Removable Media")
                ddInfo.IsRemovable = true;
            else
                ddInfo.IsRemovable = false;


            if (!diskDict.ContainsKey(diskIndex))
            {
                //Debug.WriteLine($"Adding DiskIndex {ddInfo.DiskIndex} Partitions: {ddInfo.Partitions}");

                //add
                diskDict.Add(diskIndex, ddInfo);
            }
        }
    }

    //create new instance
    SortedDictionary<string, LogicalDisk> logicalDiskToPartitionDict = new SortedDictionary<string, LogicalDisk>();

    //get info from Win32_LogicalDiskToPartition
    //this is used to associate a DiskIndex and PartitionIndex with a drive letter
    using (ManagementObjectSearcher searcherLogicalDiskToPartition = new ManagementObjectSearcher($@"SELECT * FROM Win32_LogicalDiskToPartition"))
    {
        foreach (ManagementObject objLogicalDiskToPartition in searcherLogicalDiskToPartition.Get())
        {
            if (objLogicalDiskToPartition == null)
                continue;

            string antecedent = objLogicalDiskToPartition["Antecedent"]?.ToString();
            string dependent = objLogicalDiskToPartition["Dependent"]?.ToString();
            
            string antecedentValue = antecedent.Substring(antecedent.IndexOf('=') + 1).Replace("\"", "");

            uint diskIndex = 0;
            uint partitionIndex = 0;

            //get disk index and convert to uint
            UInt32.TryParse(antecedentValue.Substring(antecedentValue.IndexOf("#") + 1, antecedentValue.IndexOf(",") - (antecedentValue.IndexOf("#") + 1)), out diskIndex);

            //get partition index and convert to uint
            UInt32.TryParse(antecedentValue.Substring(antecedentValue.LastIndexOf("#") + 1), out partitionIndex);

            string driveLetter = dependent.Substring(dependent.IndexOf("=") + 1).Replace("\"", "");

            if (diskDict.ContainsKey(diskIndex))
            {
                if (!logicalDiskToPartitionDict.ContainsKey(driveLetter))
                {
                    //add
                    logicalDiskToPartitionDict.Add(driveLetter, new LogicalDisk());
                }

                //get info from Win32_LogicalDisk
                using (ManagementObjectSearcher searcherLogicalDisk = new ManagementObjectSearcher($"SELECT Description, DeviceID, DriveType, FileSystem, Name, Size FROM Win32_LogicalDisk WHERE Name = '{driveLetter}'"))
                {
                    foreach (ManagementObject objLogicalDisk in searcherLogicalDisk.Get())
                    {
                        if (objLogicalDisk == null)
                            continue;

                        //create new instance
                        LogicalDiskInfo logicalDiskInfo = new LogicalDiskInfo();

                        //set value
                        logicalDiskInfo.Description = objLogicalDisk["Description"]?.ToString();
                        logicalDiskInfo.DeviceID = objLogicalDisk["DeviceID"]?.ToString();
                        logicalDiskInfo.DriveType = Convert.ToUInt32(objLogicalDisk["DriveType"]);
                        logicalDiskInfo.DiskIndex = diskIndex;
                        logicalDiskInfo.FileSystem = objLogicalDisk["FileSystem"]?.ToString();
                        logicalDiskInfo.Name = objLogicalDisk["Name"]?.ToString();
                        logicalDiskInfo.PartitionIndex = partitionIndex;
                        logicalDiskInfo.PartitionNumber = partitionIndex + 1; //diskpart partitions start at 1
                        logicalDiskInfo.Size = Convert.ToUInt64(objLogicalDisk["Size"]);

                        //DriveType: 2=Removable; 3=Local Disk; 4=Network Drive; 5=CD
                        if (logicalDiskInfo.DriveType == 2)
                            logicalDiskInfo.IsRemovable = true;
                        else
                            logicalDiskInfo.IsRemovable = false;

                        Debug.WriteLine($"adding logicalDiskInfo for DiskIndex: '{diskIndex}' PartitionIndex: '{partitionIndex}' PartitionNumber: '{logicalDiskInfo.PartitionNumber}'");

                        //add 
                        logicalDiskToPartitionDict[driveLetter].LogicalDiskInfos.Add(logicalDiskInfo);
                    }
                }
            }
            
        }
    }

    //add logical disk info to disk dictionary
    foreach(KeyValuePair<string, LogicalDisk> kvp in logicalDiskToPartitionDict)
    {
        List<LogicalDiskInfo> logicalDiskInfoList = kvp.Value.LogicalDiskInfos;
        
        //sort
        logicalDiskInfoList.Sort();

        foreach (LogicalDiskInfo ldInfo in logicalDiskInfoList)
        {
            //add
            diskDict[ldInfo.DiskIndex].LogicalDisks.Add(ldInfo);
        }
    }

    //only add disks that are listed as 'Removable'
    foreach(KeyValuePair<uint, DiskDriveInfo> kvp in diskDict)
    {
        if (kvp.Value.IsRemovable)
        {
            //add
            driveInfos.Add(kvp.Value);
        }
    }

    return driveInfos;
}

使用

代码语言:javascript
运行
复制
System.Diagnostics.Debug.WriteLine("--------GetUSBRemovableDiskDriveInfo----------");

foreach (DiskDriveInfo ddInfo in GetUSBRemovableDiskDriveInfo())
{
    string driveLetters = string.Empty;

    for (int i = 0; i < ddInfo.LogicalDisks.Count; i++)
    {
        if (i > 0)
            driveLetters += ", ";

        driveLetters += ddInfo.LogicalDisks[i].Name;
    }

    System.Diagnostics.Debug.WriteLine($"Caption: '{ddInfo.Caption}' Name: '{ddInfo.Name}' DiskIndex: '{ddInfo.DiskIndex}' DriveLetters: [{driveLetters}] Partitions: '{ddInfo.Partitions}' Size: '{ddInfo.Size}'");
}

可以使用System.Diagnostics.Process执行盘片脚本来清理一个或多个磁盘。有关更多信息,请参见此帖子

资源

票数 1
EN

Stack Overflow用户

发布于 2022-11-01 18:36:56

这可能是一种肮脏的方式,但是您可以交互地使用diskpart并发送命令/解析输出。由于我们无论如何都在调用diskpart,一个100%的托管代码库似乎不是目标,而是完成它的一种方法。

所以强调“肮脏”的方式,但也非常简单的功能方式:-)

有时,当有一个非常好的工作工具,如幽灵脚本或ffmpeg,我这样自动化他们。就像我在CMD提示下打字一样。

将CMD实例封装在要读取/写入的包装器中,然后在事件驱动的逻辑中驱动它。

代码语言:javascript
运行
复制
using System;
using System.Diagnostics;


namespace yourapp
{
    public class cmdShell
    {
        private Process shellProcess;

        public delegate void onDataHandler(cmdShell sender, string e);
        public event onDataHandler onData;

        public cmdShell()
        {
            try
            {
                shellProcess = new Process();
                ProcessStartInfo si = new ProcessStartInfo("cmd.exe");
                si.Arguments = "/k";
                si.RedirectStandardInput = true;
                si.RedirectStandardOutput = true;
                si.RedirectStandardError = true;
                si.UseShellExecute = false;
                si.CreateNoWindow = true;
                si.WorkingDirectory = Environment.GetEnvironmentVariable("windir");
                shellProcess.StartInfo = si;
                shellProcess.OutputDataReceived += shellProcess_OutputDataReceived;
                shellProcess.ErrorDataReceived += shellProcess_ErrorDataReceived;
                shellProcess.Start();
                shellProcess.BeginErrorReadLine();
                shellProcess.BeginOutputReadLine();
            }
            catch (Exception ex)
            {
                Trace.WriteLine(ex.Message);
            }
        }

        void shellProcess_ErrorDataReceived(object sender, DataReceivedEventArgs e)
        {
            doOnData(e.Data);
        }

        void shellProcess_OutputDataReceived(object sender, DataReceivedEventArgs e)
        {
            doOnData(e.Data);
        }

        private void doOnData(string data)
        {
            if (onData != null) onData(this, data);
        }

        public void write(string data)
        {
            try
            {
                shellProcess.StandardInput.WriteLine(data);
            }
            catch (Exception ex)
            {
                Trace.WriteLine(ex.Message);
            }
        }
    }
}
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/74261729

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档