以下代码仅使用标准库,并且在32位Python 3.6解释器中运行时没有错误,但在64位中返回错误(Windows句柄无效):
import ctypes, ctypes.wintypes
INVALID_HANDLE_VALUE = -1
DIGCF_PRESENT = 0x00000002
DIGCF_DEVICEINTERFACE = 0x00000010
ERROR_INSUFFICIENT_BUFFER = 122
ERROR_NO_MORE_ITEMS = 259
MAXIMUM_USB_STRING_LENGTH = 255
kernel32 = ctypes.windll.kernel32
setupapi = ctypes.windll.setupapi
SetupDiGetClassDevs = setupapi.SetupDiGetClassDevsW
SetupDiEnumDeviceInterfaces = setupapi.SetupDiEnumDeviceInterfaces
SetupDiGetDeviceInterfaceDetail = setupapi.SetupDiGetDeviceInterfaceDetailW
CM_Get_Parent = setupapi.CM_Get_Parent
CM_Get_Device_ID = setupapi.CM_Get_Device_IDW
CM_Request_Device_Eject = setupapi.CM_Request_Device_EjectW
class GUID(ctypes.Structure):
_fields_ = [("Data1", ctypes.c_ulong),
("Data2", ctypes.c_ushort),
("Data3", ctypes.c_ushort),
("Data4", ctypes.c_ubyte * 8)]
def __str__(self):
return '{%08X-%04X-%04X-%04X-%012X}' % (
self.Data1, self.Data2, self.Data3,
self.Data4[0] * 256 + self.Data4[1],
self.Data4[2] * (256 ** 5) +
self.Data4[3] * (256 ** 4) +
self.Data4[4] * (256 ** 3) +
self.Data4[5] * (256 ** 2) +
self.Data4[6] * 256 +
self.Data4[7])
class SP_DEVINFO_DATA(ctypes.Structure):
_fields_ = [("cbSize", ctypes.wintypes.DWORD),
("ClassGuid", GUID),
("DevInst", ctypes.wintypes.DWORD),
("Reserved", ctypes.c_void_p)
]
class SP_DEVICE_INTERFACE_DATA(ctypes.Structure):
_fields_ = [("cbSize", ctypes.wintypes.DWORD),
("InterfaceClassGuid", GUID),
("Flags", ctypes.wintypes.DWORD),
("Reserved", ctypes.c_void_p)
]
class SP_DEVICE_INTERFACE_DETAIL_DATA(ctypes.Structure):
_fields_ = [("cbSize", ctypes.wintypes.DWORD),
("DevicePath", ctypes.c_wchar*255)]
GUID_DEVINTERFACE_VOLUME = GUID(0x53F5630D, 0xB6BF, 0x11D0,
(ctypes.c_ubyte*8)(0x94, 0xF2, 0x00, 0xA0, 0xC9, 0x1E, 0xFB, 0x8B))
hDevInfo = SetupDiGetClassDevs(ctypes.byref(GUID_DEVINTERFACE_VOLUME),
0,
0,
DIGCF_PRESENT | DIGCF_DEVICEINTERFACE)
if hDevInfo == INVALID_HANDLE_VALUE:
print(ctypes.windll.GetLastError(), ctypes.windll.FormatError())
def get_device_interface(i, device=None):
interfaceData = SP_DEVICE_INTERFACE_DATA()
interfaceData.cbSize = ctypes.sizeof(SP_DEVICE_INTERFACE_DATA)
if SetupDiEnumDeviceInterfaces(
hDevInfo,
device and ctypes.byref(device) or None,
ctypes.byref(GUID_DEVINTERFACE_VOLUME),
i,
ctypes.byref(interfaceData)):
return interfaceData
elif ctypes.GetLastError() == ERROR_NO_MORE_ITEMS:
return
else:
print(ctypes.GetLastError(), ctypes.FormatError())
def connected_devices():
interface_index = 0
interface = get_device_interface(interface_index)
devices = connected_devices()
我怀疑这个问题并不是严格意义上的Python问题,而是64位和32位解释器类型与Windows交互方式的差异。
谁能解释为什么会这样?