- c - 在位数组中找到第一个零
- linux - Unix 显示有关匹配两种模式之一的文件的信息
- 正则表达式替换多个文件
- linux - 隐藏来自 xtrace 的命令
我正在尝试使用 CloseHandle 释放 USB 接口(interface)的句柄。我得到的异常(exception)是:
System.Runtime.InteropServices.SEHException (0x80004005): External component has thrown an exception. at Device.Net.APICalls.CloseHandle(SafeFileHandle hObject) at Usb.Net.Windows.UsbInterface.Dispose() in C:\GitRepos\Device.Net\src\Usb.Net\Windows\UsbInterface.cs:line 23
at Usb.Net.Windows.WindowsUsbDevice.Dispose() in C:\GitRepos\Device.Net\src\Usb.Net\Windows\WindowsUsbDevice.cs:line 131
我正在尝试在我的类的 Dispose 方法中执行此操作。
编辑背景:我尝试这样做的原因是我的代码在我第二次运行时崩溃了。根据这个article ,我必须在我用 CreateFile 创建的设备的句柄上调用 CloseHandle。无论如何,这是在我的代码中完成的,因为设备的句柄正在被处理,因为它是一个 SafeFileHandle。但是,有人告诉我,我需要在接口(interface)的句柄上调用 CloseHandle。我不知道这是不是真的。我试图这样做是为了排除不调用 CloseHandle 是错误原因的可能性。根据其他评论和研究,我现在认为这是一个错误,调用 WinUsb_Free 应该就足够了。这是正确的吗?
下面 Hans Passant 的回答告诉我删除对 CloseHandle 的调用,但正如我在评论中指出的那样,原始代码(在 master 中)从来没有首先调用 CloseHandle。当然,删除调用会起作用,但这不是问题所在。下面的问题是:使用 WinUSB API 释放 USB 接口(interface)的过程是什么?。是简单调用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 的接口(interface)上使用 IntPtr,但问题是一样的:
这里是 WinUsb_Initialize 的定义
[DllImport("winusb.dll", SetLastError = true)]
public static extern bool WinUsb_Initialize(SafeFileHandle DeviceHandle, out IntPtr InterfaceHandle);
使用 WinUSB API 发布 USB 接口(interface)的过程是怎样的?我需要在 C# 中做些不同的事情吗?为什么会出现这个错误?
最佳答案
当句柄不是正确的 kernel32 句柄或句柄已经关闭时,CloseHandle() 失败。通过挖掘 github 源代码,我发现了问题的根源:
[DllImport("winusb.dll", SetLastError = true)]
public static extern bool WinUsb_Initialize(SafeFileHandle DeviceHandle,
out SafeFileHandle InterfaceHandle);
经过编辑以适应并使问题更加明显。第二个参数的类型不正确,该函数不返回 kernel32 句柄,因此将其包装在 SafeFileHandle 中是不正确的。这是一个不透明的句柄, native api 声明中的 WINUSB_INTERFACE_HANDLE,通常是一个指针。只有一种正确的关闭方法,您必须调用 WinUsb_Free()。代码这样做了,但也调用 CloseHandle 是不正确的,注定会失败。 SafeFileHandle 提供的 CloseHandle() 调用同样会失败,您可能还没有做到这一点。
将参数类型更改为 IntPtr
。这需要更改其他几处代码,主要是在 UsbInterface 类中。同样将其 Handle 属性类型更改为 IntPtr。删除其 Dispose() 方法中的 CloseHandle() 调用。编写您自己的 SafeHandle 派生类来包装它是另一种方法,然后您将覆盖 ReleaseHandle() 以调用 WinUsb_Free()。
关于C# WinUSB 无法在接口(interface)上调用 CloseHandle,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54189056/
我正在尝试设置一个 USB 设备,使其在连接到 Windows 8 机器时自动使用 WinUSB 作为驱动程序,如所述 here . 它说: In order for the USB driver s
下午好 WinUSB 在我使用的开发计算机 (Win XP SP3) 上运行良好。我能够将新固件下载到 Cypress FX2,然后在它“重新枚举”后连接到新的 USB 设备。但是,如果我在其他几台计
我想在 C++ 上试验 USB 驱动程序。我正在使用 visual studio express 2013,但找不到 WinUSB 模板。我看过这个guide .但是它适用于 visual studi
我正在编写一个使用 WinUsb.dll 与 USB 设备通信的应用程序。这是一个用户模式库,允许通过在内核中作为其驱动程序安装的 winusb.sys 与设备进行通信。 我正在使用 C++ 和 Vi
我正在使用 Arduino 从网络读取数据并显示它。我可以使用提供的驱动程序轻松地将数据作为串行数据传递,因为它们可以识别 COM 端口,因此我可以将串行数据发送到 COM 端口。 但是,我想使用“真
您能否安装使用 WinUSB 构建的硬件驱动程序以及使用 Click-once 部署的 C# 应用程序? 最佳答案 ClickOnce 无法安装驱动程序。 ClickOnce 只是将文件从服务器位置复
我在 Windows 主机端使用 WinUSB 与我的 WINUSB USB 设备进行通信。我的 USB 设备是全速设备。我能够获取设备句柄并执行 OUT 和 IN 数据传输。 我在 FS WinUS
我正在尝试在我的项目中使用 WinUSB。我关注的指南是 http://msdn.microsoft.com/en-us/library/ff540174.aspx .这篇文章告诉我要包含以下文件:
我正在为包含 WinUSB 设备驱动程序的应用程序创建安装程序。我正在使用带有 difx 扩展名的 WiX 3.5。根据WinUSB how-to我可以创建适用于 x86、ia64 和 amd 架构的
我正在使用 Pi Zero 制作键盘原型(prototype),我计划设置 Pi Zero,使其模拟符合 HID 标准的 USB 键盘(适用于 Windows)。有很多关于如何执行此操作的指南,所以我
我正在尝试使用 LIBUSING 和 C# 通过 USB 与诺基亚 Lumia 手机 (RM-917) 进行通信。 LIBUSB 能够查看设备的信息(pid、vid 等)。但是,我无法成功写入任何端点
我正在尝试使用 CloseHandle 释放 USB 接口(interface)的句柄。我得到的异常(exception)是: System.Runtime.InteropServices.SEHEx
我有一个由 VS2010 生成的通用 SDI 应用程序,我想用它来测试 WinUsb API。我安装了当前版本的 WDK。根据我在其他地方阅读的帖子,我应该能够设置 VS2010 项目包含路径以指向
从 VS12 (update4) 平台工具集 v110 上的工作 C++\CLI 项目切换到 v110_xp 后,我的构建因找不到 winusb.h 而失败。 我可以在工作项目中看到由编译器创建的文件
可能是一些广泛使用 WinUSB API 或用户模式 USB 驱动程序的人的一个问题 - WinUSB API 或用户模式驱动程序是否可以用作 USB 连接的被动观察者,捕获中断通知、控制请求、数
我在遵循 Write a Windows desktop app based on the WinUSB template 的教程时遇到了问题来自微软的MSDN。按照说明,在我们需要创建 WinUSB
我正在尝试从 Winusb 设备获取供应商和产品 ID,并在尝试使用 winusb_GetDesicriptor() 时遇到 accessviolationexception,但无法弄清楚为什么我会收
我需要在 Linux 上实现一个驱动 USB 连接设备(医疗仪器)的应用程序。该应用程序将使用 C++(2011 标准)编写。 当前应用程序是用 C# 为 Windows 10 编写的,并使用为设备枚
我在 Windows XP(x86,服务包 3)上安装 WinUSB 驱动程序时遇到困难。我已按照 Microsoft WinUSB 指南使用 inf 文件、已签名的 cat 文件(使用 Inf2ca
我需要直接通过 USB 与简单的自定义设备通信。我有完整的通信协议(protocol)规范。遗憾的是,设备供应商没有为该设备提供 WinUSB 驱动程序。 根据 https://msdn.micros
我是一名优秀的程序员,十分优秀!