Windows10下Python挂载ISO成功但资源管理器无新盘符显示问题排查
问题:Python调用Windows API挂载ISO成功但资源管理器不显示盘符
问题场景
在Windows 10系统上尝试使用Python通过virtdisk API挂载ISO文件,代码运行后输出两个0,说明OpenVirtualDisk和AttachVirtualDisk调用均返回成功,但资源管理器中并未出现新的盘符。
原代码如下:
import ctypes from ctypes import wintypes ByteArray8 = wintypes.BYTE * 8 src = r'F:\Backup\ubuntu.iso' class GUID(ctypes.Structure): _fields_ = [ ("Data1", ctypes.c_long), ("Data2", ctypes.c_short), ("Data3", ctypes.c_short), ("Data4", ByteArray8) ] guid = GUID(0xec984aec, 0xa0f9, 0x47e9, ByteArray8(0x90, 0x1f, 0x71, 0x41, 0x5a, 0x66, 0x34, 0x5b)) class VIRTUAL_STORAGE_TYPE(ctypes.Structure): _fields_ = [ ('DeviceId', ctypes.c_ulong), ('VendorId', GUID) ] virtual_storage_type = VIRTUAL_STORAGE_TYPE(1, guid) handle = wintypes.HANDLE() Path = ctypes.c_wchar_p(src) print( ctypes.windll.virtdisk.OpenVirtualDisk( ctypes.byref(virtual_storage_type), Path, 0x000d0000, 0x00000000, None, ctypes.byref(handle) ) ) print( ctypes.windll.virtdisk.AttachVirtualDisk( handle, None, 0x00000001, 0, None, None ) )
问题原因
- 缺少盘符分配参数:调用
AttachVirtualDisk时仅指定了ATTACH_VIRTUAL_DISK_FLAG_MOUNT_READ_WRITE(0x1),未添加ATTACH_VIRTUAL_DISK_FLAG_ASSIGN_DRIVE_LETTER(0x2)标志,系统仅完成挂载但不会自动分配盘符。 - 未触发资源管理器刷新:即使系统分配了盘符,也需要主动通知资源管理器刷新才能显示新挂载的卷。
正确挂载方法
修改代码,添加盘符分配标志,并在挂载完成后通知资源管理器刷新:
import ctypes from ctypes import wintypes # 定义常量 ATTACH_VIRTUAL_DISK_FLAG_MOUNT_READ_WRITE = 0x00000001 ATTACH_VIRTUAL_DISK_FLAG_ASSIGN_DRIVE_LETTER = 0x00000002 SHCNE_DRIVEADD = 0x00000001 SHCNF_FLUSH = 0x00000010 ByteArray8 = wintypes.BYTE * 8 src = r'F:\Backup\ubuntu.iso' class GUID(ctypes.Structure): _fields_ = [ ("Data1", ctypes.c_ulong), # 修正字节对齐问题,替换原c_long ("Data2", ctypes.c_ushort), ("Data3", ctypes.c_ushort), ("Data4", ByteArray8) ] # ISO对应的Vendor GUID guid = GUID(0xec984aec, 0xa0f9, 0x47e9, ByteArray8(0x90, 0x1f, 0x71, 0x41, 0x5a, 0x66, 0x34, 0x5b)) class VIRTUAL_STORAGE_TYPE(ctypes.Structure): _fields_ = [ ('DeviceId', ctypes.c_ulong), ('VendorId', GUID) ] virtual_storage_type = VIRTUAL_STORAGE_TYPE(1, guid) handle = wintypes.HANDLE() Path = ctypes.c_wchar_p(src) # 打开虚拟磁盘 open_result = ctypes.windll.virtdisk.OpenVirtualDisk( ctypes.byref(virtual_storage_type), Path, 0x00000001 | 0x00000002 | 0x00000004, # GENERIC_READ | GENERIC_WRITE | GENERIC_EXECUTE 0, None, ctypes.byref(handle) ) print(f"OpenVirtualDisk result: {open_result}") if open_result == 0: # 挂载虚拟磁盘,同时分配盘符 attach_result = ctypes.windll.virtdisk.AttachVirtualDisk( handle, None, ATTACH_VIRTUAL_DISK_FLAG_MOUNT_READ_WRITE | ATTACH_VIRTUAL_DISK_FLAG_ASSIGN_DRIVE_LETTER, 0, None, None ) print(f"AttachVirtualDisk result: {attach_result}") if attach_result == 0: # 通知资源管理器刷新,显示新盘符 ctypes.windll.shell32.SHChangeNotify(SHCNE_DRIVEADD, SHCNF_FLUSH, None, None) # 关闭句柄释放资源 ctypes.windll.kernel32.CloseHandle(handle)
关键修改说明
- 修正GUID结构:将
Data1类型从c_long改为c_ulong,避免因系统位数差异导致的字节对齐错误。 - 添加盘符分配标志:在
AttachVirtualDisk的Flags参数中组合ATTACH_VIRTUAL_DISK_FLAG_ASSIGN_DRIVE_LETTER,让系统自动分配可用盘符。 - 资源管理器刷新:调用
SHChangeNotify通知系统刷新驱动器列表,确保新盘符在资源管理器中显示。 - 关闭句柄:添加
CloseHandle释放资源,避免内存泄漏。
内容的提问来源于stack exchange,提问作者JW Liao
相关产品推荐
相关产品推荐

