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

如何在Windows10下无需调用Shell,用Python弹出外部驱动器?

在Windows 10下用Python实现备份后自动弹出外部驱动器

下面给你两种可行的实现方案,都是Windows原生支持的,不需要额外安装第三方库:

方法1:调用系统自带的diskpart命令(简单易上手)

Windows自带的diskpart工具可以安全卸载外部驱动器,我们可以用Python的subprocess模块调用它完成弹出操作。

代码示例

import subprocess

def eject_drive(drive_letter):
    # 生成diskpart执行脚本,注意盘符要去掉冒号
    diskpart_cmd = f"select volume {drive_letter[:-1]}\nremove all dismount\n"
    # 调用diskpart执行脚本
    try:
        subprocess.run(
            ["diskpart", "/s", "-"],
            input=diskpart_cmd.encode("utf-8"),
            check=True,
            stdout=subprocess.PIPE,
            stderr=subprocess.PIPE
        )
        print(f"驱动器 {drive_letter} 已成功弹出")
    except subprocess.CalledProcessError as e:
        print(f"弹出失败:{e.stderr.decode('utf-8')}")

# 备份完成后调用,替换成你的外部驱动器盘符(比如"E:")
eject_drive("E:")

注意事项

  • 脚本需要以管理员权限运行,否则diskpart无法执行卸载操作
  • 执行弹出前,务必确保所有备份文件已经完全写入驱动器,可以在文件复制完成后调用os.sync()(或者用shutil.copy2替代普通复制,它会确保文件元数据也同步)

方法2:用ctypes调用Windows原生API(更稳定)

如果不想依赖外部命令,可以直接调用Windows的设备管理API来弹出驱动器,这种方式更底层,稳定性更好。

代码示例

import ctypes
from ctypes import wintypes

# 加载Windows API库
setupapi = ctypes.WinDLL("setupapi.dll")
cfgmgr32 = ctypes.WinDLL("cfgmgr32.dll")

# 定义API函数的参数和返回值类型
setupapi.SetupDiGetClassDevsW.argtypes = [wintypes.LPCGUID, wintypes.LPCWSTR, wintypes.HWND, wintypes.DWORD]
setupapi.SetupDiGetClassDevsW.restype = wintypes.HDEVINFO

setupapi.SetupDiEnumDeviceInfo.argtypes = [wintypes.HDEVINFO, wintypes.DWORD, wintypes.PSP_DEVINFO_DATA]
setupapi.SetupDiEnumDeviceInfo.restype = wintypes.BOOL

cfgmgr32.CM_Get_Device_IDW.argtypes = [wintypes.DWORD, wintypes.LPWSTR, wintypes.DWORD, wintypes.DWORD]
cfgmgr32.CM_Get_Device_IDW.restype = wintypes.DWORD

cfgmgr32.CM_Request_Device_EjectW.argtypes = [wintypes.HDEVINFO, wintypes.PSP_DEVINFO_DATA, wintypes.LPCWSTR, wintypes.DWORD, wintypes.DWORD]
cfgmgr32.CM_Request_Device_EjectW.restype = wintypes.DWORD

def eject_drive(device_instance_id):
    # 获取当前连接的USB存储设备列表
    hdevinfo = setupapi.SetupDiGetClassDevsW(None, "USBSTOR", None, 0x00000001)  # DIGCF_PRESENT
    if hdevinfo == wintypes.HDEVINFO(-1).value:
        raise ctypes.WinError()

    devinfo_data = wintypes.SP_DEVINFO_DATA()
    devinfo_data.cbSize = ctypes.sizeof(devinfo_data)

    index = 0
    while setupapi.SetupDiEnumDeviceInfo(hdevinfo, index, ctypes.byref(devinfo_data)):
        index += 1
        # 获取当前设备的实例ID
        buf = ctypes.create_unicode_buffer(1024)
        if cfgmgr32.CM_Get_Device_IDW(devinfo_data.DevInst, buf, ctypes.sizeof(buf)//2, 0) != 0:
            continue
        if buf.value == device_instance_id:
            # 执行弹出操作
            result = cfgmgr32.CM_Request_Device_EjectW(hdevinfo, ctypes.byref(devinfo_data), None, 0, 0)
            if result != 0:
                raise ctypes.WinError(result)
            print("驱动器已成功弹出")
            break
    else:
        raise ValueError("未找到目标设备")

    setupapi.SetupDiDestroyDeviceInfoList(hdevinfo)

# 使用前需要替换成你的外部驱动器的设备实例ID
# 获取方式:设备管理器 -> 找到你的外部驱动器 -> 属性 -> 详细信息 -> 设备实例路径
# eject_drive("USBSTOR\\DISK&VEN_SANDISK&PROD_CRUZER_GLIDE&REV_1.27\\1234567890ABCDEF&0")

注意事项

  • 设备实例ID是固定的(同一台设备同一USB口),可以提前获取后硬编码到脚本里
  • 同样需要确保备份文件完全写入后再执行弹出操作

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.17 09:10:31