writefile lasterror 5

本文探讨了使用Windows API的WriteFile函数在写入FAT32或NTFS格式化磁盘时遇到错误码5的问题。文章分析了两种特殊情况下WriteFile仍能写入磁盘的方法:磁盘为RAW格式或未配置状态,并讨论了通过DeviceIoControl配置FSCTL_LOCK_VOLUME及FSCTL_UNLOCK_VOLUME的操作效果。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

windows api writefile写磁盘数据的时候lasterror返回错误码5的情况,该问题是由于windows format格式化fat32或者ntfs之后无法写(可能被磁盘保护),有两种方法可以执行writefile,一种是磁盘变成RAW格式,表示没有格式化的状态,另外一种是磁盘未配置(执行diskpart clean)。以上两种情况下,writefile可以写磁盘。另外网上找了下关于使用DeviceIoControl配置FSCTL_LOCK_VOLUME以及FSCTL_UNLOCK_VOLUME相关操作,writefile依旧lasterror返回错误码5,不知道有没有在格式化fat32和ntfs格式化的情况下,有方法可以让writefile可以写磁盘。

你遇到的错误是: ``` hid.HIDException: WriteFile: (0x00000057) 参数错误。 ``` 这是 Windows API 返回的错误代码: ``` ERROR_INVALID_PARAMETER (0x00000057) ``` 表示你传给 `WriteFile` 的参数不合法。 --- ## 🧨 问题定位 你使用了如下代码发送命令: ```python h.write(bytes(cmd_bytes)) ``` 其中 `cmd_bytes` 是一个长度为 64 的字节数组。 但你遇到了错误: ``` WriteFile: 参数错误 ``` 这意味着你发送的数据格式或长度 **不符合设备要求**。 --- ## ✅ 问题分析 ### 1. **HID 设备的写入要求** - 有些 HID 设备只接受 **固定长度的报告(Report)**。 - 有些设备要求 **第一个字节是 Report ID**,有些则 **不包含 Report ID**。 - 如果你发送的数据长度不匹配,或者设备不接受 Report ID,就会报错。 ### 2. **你的设备是否接受 Report ID?** 你使用了: ```python cmd_bytes = [0] + [ord(c) for c in command] + [0] * ... ``` 即第一个字节是 `0`(Report ID),这可能 **不适用于你的设备**。 --- ## ✅ 解决方案 ### ✅ 方案 1:尝试不带 Report ID 发送 修改 `send_command()` 函数: ```python def send_command(h, command): # 不包含 Report ID cmd_bytes = [ord(c) for c in command] # 补足到 64 字节 cmd_bytes += [0] * (64 - len(cmd_bytes)) h.write(bytes(cmd_bytes)) time.sleep(0.1) ``` --- ### ✅ 方案 2:尝试使用正确的 Report ID 如果你知道设备的 Report ID 是 `1` 或其他值(可通过 USB 协议分析工具或设备文档确认),可以调整: ```python cmd_bytes = [1] + [ord(c) for c in command] + ... ``` --- ### ✅ 方案 3:使用 `bytearray` 构造固定长度的缓冲区 ```python def send_command(h, command): buf = bytearray(64) # 64 字节缓冲区 for i, c in enumerate(command): if i >= 63: break buf[i] = ord(c) h.write(buf) time.sleep(0.1) ``` --- ## ✅ 方案 4:使用 `hidapi` 命令行调试工具(推荐) 你可以使用 `hidapitester` 或 `HID Report Tool` 等工具手动发送 `data?;` 指令,看看设备是否响应,以确认: - 是否需要 Report ID - 数据长度是否正确 - 是否支持 ASCII 指令 下载地址: - [https://github.com/todbot/hidapitester](https://github.com/todbot/hidapitester) 使用方法: ```bash hidapitester --vid 0x10c4 --pid 0xea80 --write "64:64 64 'data?;'" ``` --- ## ✅ 补充建议:读取设备报告描述符 你可以使用如下代码打印设备的报告描述符(Report Descriptor),以确认设备支持的输入输出格式: ```python import hid for device in hid.enumerate(): if device['vendor_id'] == 0x10c4 and device['product_id'] == 0xea80: print(f"Report Descriptor: {device['report_descriptor']}") ``` --- ## ✅ 最终推荐代码(无 Report ID) ```python import hid import struct import time def find_unit_8804_device(): for device in hid.enumerate(): if device['vendor_id'] == 0x10c4 and device['product_id'] == 0xea80: print(f"Found UNIT 8804: {device['product_string']}") return device print("UNIT 8804 not found") return None def send_command(h, command): buf = bytearray(64) for i, c in enumerate(command): if i >= 63: break buf[i] = ord(c) h.write(buf) time.sleep(0.1) def read_double(h): data = h.read(8) if len(data) == 8: return struct.unpack('<d', data)[0] else: print("Failed to read 8 bytes") return None def parse_flags(flags): unit_type = (flags >> 8) & 0x0F unit_scale = (flags >> 12) & 0x07 sign = '-' if (flags >> 19) & 0x01 else '' unit_map = { 0: 'V', 1: 'A', 2: 'Ω', 3: 'Hz', 4: '℃', 5: '℉', 7: 'F', 8: 'β', 9: '%' } scale_map = { 0: 'n', 1: 'μ', 2: 'm', 3: '', 4: 'k', 5: 'M', 6: 'G' } return f"{sign}{scale_map.get(unit_scale, '?')}{unit_map.get(unit_type, '?')}" def read_unit_8804(): device_info = find_unit_8804_device() if not device_info: return try: h = hid.Device(path=device_info['path']) print("Connected to UNIT 8804") while True: send_command(h, "data?;") value = read_double(h) if value is not None: send_command(h, "disp?;") flags_data = h.read(8) if len(flags_data) == 8: flags = struct.unpack('<Q', flags_data)[0] unit_str = parse_flags(flags) print(f"Measurement: {value} {unit_str}") else: print(f"Measurement: {value}") else: print("No valid data received.") time.sleep(1) except KeyboardInterrupt: print("Exiting...") finally: h.close() if __name__ == "__main__": read_unit_8804() ``` --- ##
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值