我正在尝试使用 CloseHandle 释放 USB 接口的句柄。我得到的例外是:
System.Runtime.InteropServices.SEHException (0x80004005):外部组件已引发异常。在 Device.Net.APICalls.CloseHandle(SafeFileHandle hObject) 在 Usb.Net.Windows.UsbInterface.Dispose() 在 C:\GitRepos\Device.Net\src\Usb.Net\Windows\UsbInterface.cs:第 23 行在
Usb .Net.Windows.WindowsUsbDevice.Dispose() 在 C:\GitRepos\Device.Net\src\Usb.Net\Windows\WindowsUsbDevice.cs:131 行
我正在尝试在我班级的 Dispose 方法中执行此操作。
编辑背景:我试图这样做的原因是我的代码在我第二次运行它时崩溃了。根据这篇文章,我必须在我用 CreateFile 创建的设备的句柄上调用 CloseHandle。无论如何,这是在我的代码中完成的,因为设备的句柄正在被释放,因为它是一个 SafeFileHandle。但是,有人告诉我,我需要在接口的句柄上调用 CloseHandle。我不知道这是否属实。我试图这样做以排除不调用 CloseHandle 是导致该错误的原因的可能性。根据其他评论和研究,我现在认为这是一个错误,调用 WinUsb_Free 就足够了。这个对吗?
Hans Passant 在下面的回答是告诉我删除对 CloseHandle 的调用,但正如我在评论中指出的那样,原始代码(在 master 中)从来没有首先调用 CloseHandle。当然,删除呼叫会起作用,但这不是问题。下面的问题是:用WinUSB API发布USB接口的流程是什么?. 仅仅是调用 WinUsb_Free 吗?这就是我所拥有的所有信息让我相信的。
这是我问这个问题之前的原始处置方法。它没有对 CloseHandle 的调用。
public void Dispose()
{
if (_IsDisposed) return;
_IsDisposed = true;
var isSuccess = WinUsbApiCalls.WinUsb_Free(Handle);
WindowsDeviceBase.HandleError(isSuccess, "Interface could not be disposed");
}
从 WindowsUsbInterface(https://github.com/MelbourneDeveloper/Device.Net/blob/9ebc122a2755dda2824c6eda961d092f2f6e83b5/src/Usb.Net/Windows/WindowsUsbDevice.cs#L122):
public override void Dispose()
{
if (_IsDisposing) return;
_IsDisposing = true;
try
{
foreach (var usbInterface in _UsbInterfaces)
{
usbInterface.Dispose();
}
_UsbInterfaces.Clear();
_DeviceHandle?.Dispose();
_DeviceHandle = null;
base.Dispose();
}
catch (Exception ex)
{
Logger.Log("Error disposing of device", ex, nameof(WindowsUsbDevice));
}
_IsDisposing = false;
}
来自 UsbInterface(https://github.com/MelbourneDeveloper/Device.Net/blob/9ebc122a2755dda2824c6eda961d092f2f6e83b5/src/Usb.Net/Windows/UsbInterface.cs#L18):
public void Dispose()
{
var isSuccess = WinUsbApiCalls.WinUsb_Free(Handle);
WindowsDeviceBase.HandleError(isSuccess, "Interface could not be disposed");
isSuccess = APICalls.CloseHandle(Handle);
WindowsDeviceBase.HandleError(isSuccess, "Interface could not be disposed");
}
API 调用定义(https://github.com/MelbourneDeveloper/Device.Net/blob/CloseHandle/src/Device.Net/Windows/APICalls.cs):
[DllImport("kernel32.dll", SetLastError = true)]
public static extern bool CloseHandle(SafeFileHandle hObject);
我也尝试过简单地处理句柄,因为它是 SafeFileHandle,但 SafeFileHandle 的 Dispose 方法给了我相同的错误消息。这向我表明 SafeFileHandle 的 Dispose 方法可能也在调用 CloseHandle,并且正在发生同样的问题。
其他人提到我应该使用 IntPtr 而不是 SafeFileHandle。所以,我尝试在 CloseHandle 的界面上使用 IntPtr,但问题是一样的:
[DllImport("winusb.dll", SetLastError = true)]
public static extern bool WinUsb_Initialize(SafeFileHandle DeviceHandle, out IntPtr InterfaceHandle);
使用 WinUSB API 发布 USB 接口的流程是什么?在 C# 中我需要做些不同的事情吗?为什么会出现这个错误?