亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

C# WinUSB 無法在接口上調用 CloseHandle

C# WinUSB 無法在接口上調用 CloseHandle

C#
揚帆大魚 2022-07-23 09:16:14
我正在嘗試使用 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 的調用。來自 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,并且正在發生同樣的問題。
查看完整描述

2 回答

?
largeQ

TA貢獻2039條經驗 獲得超8個贊

當句柄不是正確的 kernel32 句柄或句柄已關閉時,CloseHandle() 會失敗。通過挖掘 github 源代碼,我發現了問題的根源:


    [DllImport("winusb.dll", SetLastError = true)]

    public static extern bool WinUsb_Initialize(SafeFileHandle DeviceHandle,

                                                out SafeFileHandle InterfaceHandle);

編輯以適應并使問題更加明顯。第二個參數的類型不正確,該函數不返回 kernel32 句柄,因此將其包裝在 SafeFileHandle 中是不正確的。這是一個不透明的句柄,本機 api 聲明中的 WINUSB_INTERFACE_HANDLE,通常是引擎蓋下的指針。只有一種正確的方法可以關閉它,您必須調用 WinUsb_Free()。代碼這樣做了,但調用 CloseHandle也是不正確的,注定會失敗。SafeFileHandle 提供的 CloseHandle() 調用同樣會失敗,您可能還沒有到那一步。


將參數類型更改為IntPtr. 這需要其他幾處代碼更改,主要是在 UsbInterface 類中。同樣將其 Handle 屬性類型更改為 IntPtr。刪除其 Dispose() 方法中的 CloseHandle() 調用。編寫您自己的 SafeHandle 派生類來包裝它是另一種方式,然后您將重寫 ReleaseHandle() 以調用 WinUsb_Free()。


查看完整回答
反對 回復 2022-07-23
?
月關寶盒

TA貢獻1772條經驗 獲得超5個贊

我認為這個問題的答案是沒有必要在 USB 接口上調用 CloseHandle。根據本頁頂部的 Dispose 方法,調用 WinUsb_Free 應該足以釋放接口。只需調用 CloseHandle 即可釋放 CreateFile 創建的設備的句柄。


public void Dispose()

{

    if (_IsDisposed) return;

    _IsDisposed = true;


    var isSuccess = WinUsbApiCalls.WinUsb_Free(Handle);

    WindowsDeviceBase.HandleError(isSuccess, "Interface could not be disposed");

}

這篇文章說得很清楚。


CloseHandle 釋放由 CreateFile 創建的句柄,如步驟 1 中所述。

WinUsb_Free 釋放設備的 WinUSB 接口句柄,由 WinUsb_Initialize 返回。

Hans Passant 還推薦:


在 Dispose() 方法中刪除 CloseHandle() 調用


此外,來自漢斯·帕桑特:


第二個參數的類型不正確,該函數不返回 kernel32 句柄,因此將其包裝在 SafeFileHandle 中是不正確的。這是一個不透明的句柄,本機 api 聲明中的 WINUSB_INTERFACE_HANDLE,通常是引擎蓋下的指針。只有一種正確的方法可以關閉它,您必須調用 WinUsb_Free()。


這并不直接涉及我所問的問題,但這是一個公平的觀點。正如 Hans 指出的那樣,我不能在 WinUsb_Initialize 返回的句柄上調用 Dispose() 的原因是這樣做會在后臺調用 CloseHandle,而 WinUsb_Initialize 返回的第二個參數不是 kernel32 句柄,所以 CloseHandle() 只是贏了'無論如何都行不通。這只是導致似乎沒有任何跡象表明有必要在接口上調用 CloseHandle。所以,我相信我遇到的問題(單獨的問題)與不調用 CloseHandle 無關。這似乎是固件本身的問題,制造商似乎已經確認了這一點。更多細節即將到來。


注意:如果我錯了,請告訴我為什么我錯了,并指出一個使用 CloseHandle 關閉 USB 接口上的句柄的示例。


查看完整回答
反對 回復 2022-07-23
  • 2 回答
  • 0 關注
  • 399 瀏覽

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號