首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 更多程式語言 >> 程式設計綜合問答

C# 通過 CreateFile 打開 USB 設備返回 -1 (INVALID_HANDLE_VALUE) 原因分析

     編輯:程式設計綜合問答

核心結論

**用戶態應用程序無法直接通過 CreateFile("\\\\.\\PNPDeviceID...") 打開 USB 設備驅動程序對象**。Windows 內核禁止非驅動程序代碼打開設備對象 (\\Device\\...),INVALID_HANDLE_VALUE (-1) 即此意。

正確 USB 通信架構

User App (C#) 
    │  WinUSB / libusb / HID API / SerialPort
    ▼
User-mode Driver Framework (UMDF) / Kernel Driver (KMDF)
    │  IRP_MJ_READ / WRITE / DEVICE_CONTROL
    ▼
USB Device Hardware

可行方案對比

方案適用場景關鍵組件C# 調用方式
WinUSB自定義 USB 設備 (無標準類驅動)WinUSB.dll, WinUSB.sysP/Invoke WinUSB API 或 Microsoft.WinUSB NuGet
libusbK / libusb-win32跨平台、開源驅動libusbK.sys, libusb.dllLibUsbDotNet NuGet
HID Class鍵鼠、游戲手柄、自定義 HIDhid.dll (系統自帶)HidD_GetHidGuid + CreateFile 路徑為 \\\\?\\hid#...
CDC/ACM (虛擬串口)Arduino、模塊、調試口usbser.sysSerialPort 類 (COMx)

WinUSB 完整流程示例

  1. 編寫 INF 安裝 WinUSB 驅動綁定到設備 VID/PID。
  2. C# 獲取設備路徑:
    Guid guid = WinUSB_GUID; // 從 INF 獲取
    devicePath = GetDevicePath(guid); // SetupDiGetDeviceInterfaceDetail
  3. 打開句柄:
    SafeFileHandle handle = CreateFile(devicePath, GENERIC_READ|GENERIC_WRITE, FILE_SHARE_READ|FILE_SHARE_WRITE, IntPtr.Zero, OPEN_EXISTING, FILE_FLAG_OVERLAPPED, IntPtr.Zero);
  4. 初始化 WinUSB:
    WinUsb_Initialize(handle, out winUsbHandle);
  5. 傳輸:
    WinUsb_WritePipe(winUsbHandle, 0x01, buffer, length, out transferred, IntPtr.Zero);

代碼庫推薦

避坑指南

  • **不要嘗試打開 PNPDeviceID 字符串**,它不是文件路徑。
  • 驅動簽名:Win10/11 需簽名驅動,測試可啟用「測試模式」或使用已簽名的 libusbK。
  • 權限:訪問 USB 設備通常需管理員權限,或在清單聲明 uiAccess。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved