Я пытаюсь освободить дескриптор интерфейса USB с помощью CloseHandle. Исключение, которое я получаю:
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 моего класса.
Редактировать фон:
Причина, по которой я пытаюсь это сделать, заключается в том, что мой код дает сбой при втором запуске. Согласно этой статье , я должен вызвать CloseHandle на дескрипторе устройства, которое я создал с помощью CreateFile. В любом случае это сделано в моем коде, потому что дескриптор устройства удаляется, потому что это SafeFileHandle. Но кто-то сказал мне, что мне нужно вызвать CloseHandle на дескрипторе для интерфейса. Я не знаю, правда ли это или нет. Я пытаюсь сделать это, чтобы исключить возможность того, что не вызов CloseHandle является причиной ошибки. Основываясь на других комментариях и исследованиях, я теперь считаю, что это было ошибкой и достаточно вызова WinUsb_Free. Это правильно?
Ответ Ханса Пассанта, приведенный ниже, говорит мне, чтобы я удалил вызов CloseHandle, но, как я уже отмечал в комментариях, оригинальный код (в master) никогда не вызывал CloseHandle. Конечно, удаление вызова будет работать, но это не вопрос. Вопрос, приведенный ниже: Как происходит выпуск интерфейса USB с API-интерфейсом WinUSB? . Это просто для вызова 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, но метод Dispose для SafeFileHandle выдает мне то же сообщение об ошибке. Это говорит мне о том, что метод Dispose SafeFileHandle, вероятно, также вызывает CloseHandle, и возникает та же проблема.
Другие люди упоминали, что я должен использовать IntPtr вместо SafeFileHandle. Итак, я попытался использовать IntPtr в интерфейсе для CloseHandle, но проблема та же:
Вот определение WinUsb_Initialize
[DllImport("winusb.dll", SetLastError = true)]
public static extern bool WinUsb_Initialize(SafeFileHandle DeviceHandle, out IntPtr InterfaceHandle);
Как происходит выпуск интерфейса USB с WinUSB API? Есть ли что-то, что мне нужно сделать по-другому в C #? Почему возникла эта ошибка?