You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用Python仅列出外部USB存储设备?(含USB硬盘、U盘等)

仅列出Windows下外部USB存储设备的Python实现(低依赖)

方法一:使用pywin32库(win32api 扩展)

如果已经安装了pywin32,可以结合win32api和WMI接口精准筛选USB设备,排除软盘等其他可移动存储:

import win32api
import win32com.client

def get_usb_drives():
    usb_drives = []
    # 获取所有逻辑驱动器,过滤掉末尾空字符串
    drives = win32api.GetLogicalDriveStrings().split('\x00')[:-1]
    
    # 通过WMI查询USB磁盘设备
    wmi = win32com.client.GetObject("winmgmts:")
    for disk in wmi.InstancesOf("Win32_DiskDrive"):
        # 仅筛选接口类型为USB的设备
        if disk.InterfaceType == "USB":
            # 关联磁盘分区与逻辑驱动器
            for partition in disk.Associators_("Win32_DiskDriveToDiskPartition"):
                for logical_disk in partition.Associators_("Win32_LogicalDiskToPartition"):
                    drive_path = f"{logical_disk.DeviceID}\\"
                    if drive_path in drives:
                        usb_drives.append(drive_path)
    # 去重返回
    return list(set(usb_drives))

print(get_usb_drives())

说明:该方法通过WMI直接关联USB磁盘设备与逻辑驱动器字母,准确性高,依赖pywin32库(通常通过pip install pywin32安装)。

方法二:使用ctypes(纯标准库,无额外依赖)

如果需要零第三方依赖,可使用Python标准库ctypes调用Windows原生API实现:

import ctypes
from ctypes import wintypes

# 加载Windows系统库
kernel32 = ctypes.WinDLL('kernel32', use_last_error=True)
setupapi = ctypes.WinDLL('setupapi', use_last_error=True)
cfgmgr32 = ctypes.WinDLL('cfgmgr32', use_last_error=True)

# 定义常量与结构体
DRIVE_REMOVABLE = 2
GUID_DEVINTERFACE_DISK = '{53F56307-B6BF-11D0-94F2-00A0C91EFB8B}'
DIGCF_PRESENT = 0x00000002
DIGCF_DEVICEINTERFACE = 0x00000010

class SP_DEVICE_INTERFACE_DATA(ctypes.Structure):
    _fields_ = [
        ("cbSize", wintypes.DWORD),
        ("InterfaceClassGuid", wintypes.GUID),
        ("Flags", wintypes.DWORD),
        ("Reserved", wintypes.LPVOID)
    ]

class SP_DEVINFO_DATA(ctypes.Structure):
    _fields_ = [
        ("cbSize", wintypes.DWORD),
        ("ClassGuid", wintypes.GUID),
        ("DevInst", wintypes.DWORD),
        ("Reserved", wintypes.LPVOID)
    ]

def get_usb_drives_ctypes():
    usb_drives = []
    # 获取所有逻辑驱动器
    buf_size = kernel32.GetLogicalDriveStringsW(0, None)
    buf = ctypes.create_unicode_buffer(buf_size)
    kernel32.GetLogicalDriveStringsW(buf_size, buf)
    drives = [buf[i:i+4] for i in range(0, buf_size, 4) if buf[i]]
    
    # 枚举所有磁盘设备接口
    disk_guid = wintypes.GUID(GUID_DEVINTERFACE_DISK)
    hdevinfo = setupapi.SetupDiGetClassDevsW(ctypes.byref(disk_guid), None, None, DIGCF_PRESENT | DIGCF_DEVICEINTERFACE)
    if hdevinfo == wintypes.HANDLE(-1).value:
        return usb_drives
    
    interface_data = SP_DEVICE_INTERFACE_DATA()
    interface_data.cbSize = ctypes.sizeof(SP_DEVICE_INTERFACE_DATA)
    devinfo_data = SP_DEVINFO_DATA()
    devinfo_data.cbSize = ctypes.sizeof(SP_DEVINFO_DATA)
    
    index = 0
    while setupapi.SetupDiEnumDeviceInterfaces(hdevinfo, None, ctypes.byref(disk_guid), index, ctypes.byref(interface_data)):
        index += 1
        # 获取设备路径
        req_size = wintypes.DWORD()
        setupapi.SetupDiGetDeviceInterfaceDetailW(hdevinfo, ctypes.byref(interface_data), None, 0, ctypes.byref(req_size), None)
        detail_buf = ctypes.create_string_buffer(req_size.value)
        if not setupapi.SetupDiGetDeviceInterfaceDetailW(hdevinfo, ctypes.byref(interface_data), detail_buf, req_size, None, ctypes.byref(devinfo_data)):
            continue
        
        # 判断设备是否为USB类型
        dev_inst = devinfo_data.DevInst
        parent_devinst = wintypes.DWORD()
        if cfgmgr32.CM_Get_Parent(ctypes.byref(parent_devinst), dev_inst, 0) != 0:
            continue
        
        # 获取硬件ID验证USB标识
        hw_id_buf = ctypes.create_unicode_buffer(256)
        cfgmgr32.CM_Get_Device_IDW(parent_devinst.value, hw_id_buf, ctypes.sizeof(hw_id_buf)//2, 0)
        if 'USB' not in hw_id_buf.value:
            continue
        
        # 映射到逻辑驱动器字母
        device_path = ctypes.wstring_at(detail_buf)
        volume_buf = ctypes.create_unicode_buffer(1024)
        kernel32.GetVolumePathNamesForVolumeNameW(device_path, volume_buf, ctypes.sizeof(volume_buf)//2, None)
        if volume_buf.value:
            drive_letter = volume_buf.value.split('\\')[0] + '\\'
            if drive_letter in drives:
                usb_drives.append(drive_letter)
    
    setupapi.SetupDiDestroyDeviceInfoList(hdevinfo)
    return list(set(usb_drives))

print(get_usb_drives_ctypes())

说明:该方法完全基于Python标准库,直接调用Windows底层API,无需安装任何第三方包,适合对依赖严格的场景。


内容的提问来源于stack exchange,提问作者Basj

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.19 01:46:33