使用C++WRL可视化打开UsbDevice-ERROR_INVALID_HANDLE
visual Open UsbDevice using C++ WRL - ERROR_INVALID_HANDLE
我试图获得一个引用特定USB设备的Windows::Devices::Usb::UsbDevice
对象,以便将其传递给第三方插件。由于项目限制,我无法使用C++/CX
扩展。
在查看了无数的线程、答案和引用之后,我提出了一个初始实现,它可以在我需要的WinRT类上调用静态方法。唯一的问题是,即使没有调用会导致HRESULT
失败,但对FromIdAsync
的最后一次调用也不起作用,使我的ERROR_INVALID_HANDLE
(6
)成为GetLastError()
的结果。
简单地读取错误名称会让我觉得错误在于获取设备的ID,因为这是我在该调用中传递的唯一句柄,但我尝试传递一个常量字符串(我知道这是正确的),结果相同。
这就是我调用FromIdAsync
*的方式:
// Retrieves static methods for UsbDevice class
ComPtr<IUsbDeviceStatics> usbDevSt;
hr = GetActivationFactory(
HStringReference(RuntimeClass_Windows_Devices_Usb_UsbDevice).Get(),
&usbDevSt
);
// Creates an event to work as a 'semaphore', for waiting for the 'FromIdAsync'
// call to be completed
Event openEvent(CreateEventEx(
nullptr,
nullptr,
CREATE_EVENT_MANUAL_RESET,
WRITE_OWNER | EVENT_ALL_ACCESS
));
if (!openEvent.IsValid()) return nullptr;
// Setups a callback for when the device enumeration is done
auto asyncOpenCb = Callback<IAsyncOperationCompletedHandler<UsbDevice*>>(
[&openEvent](IAsyncOperation<UsbDevice*> *opHandler, AsyncStatus status) -> HRESULT {
if (!opHandler || status != AsyncStatus::Completed) {
DWORD x = GetLastError(); // ERROR_INVALID_HANDLE (6)
}
SetEvent(openEvent.Get());
return S_OK;
}
);
// Invokes the 'asyncOpenOp' method, equivalent to UsbDevice::FromIdAsync(String)
ComPtr<IAsyncOperation<UsbDevice*>> asyncOpenOp;
hr = usbDevSt->FromIdAsync(
devId.Get(),
asyncOpenOp.GetAddressOf()
);
// Registers completed callback
hr = asyncOpenOp->put_Completed(asyncOpenCb.Get());
// Waits for open operation to complete before continuing
WaitForSingleObjectEx(openEvent.Get(), INFINITE, false);
// Retrieves the result from the asynchronous call
ComPtr<IUsbDevice> dev;
hr = asyncOpenOp->GetResults(dev.GetAddressOf());
这就是我得到devId
*的方式:
// Retrieve static methods for DeviceInformation class
ComPtr<IDeviceInformationStatics> devInfoSt;
HRESULT hr = GetActivationFactory(
HStringReference(RuntimeClass_Windows_Devices_Enumeration_DeviceInformation).Get(),
&devInfoSt
);
// Create an event to work as a 'semaphore', for waiting for the 'FindAllAsyncAqsFilter' call to be completed
Event findEvent(CreateEventEx(
nullptr,
nullptr,
CREATE_EVENT_MANUAL_RESET,
WRITE_OWNER | EVENT_ALL_ACCESS
));
if (!findEvent.IsValid()) return nullptr;
// Setup a callback for when the device enumeration is done
auto asyncFindCb = Callback<IAsyncOperationCompletedHandler<DeviceInformationCollection*>>(
[&findEvent](IAsyncOperation<DeviceInformationCollection*> *opHandler, AsyncStatus status) -> HRESULT {
SetEvent(findEvent.Get());
return S_OK;
}
);
// Invoke the 'FindAllAsyncAqsFilter' method, equivalent to DeviceInformation::FindAllAsync(String)
ComPtr<IAsyncOperation<DeviceInformationCollection*>> asyncFindOp;
hr = devInfoSt->FindAllAsyncAqsFilter(
HStringReference(DEVICE_FILTER).Get(),
asyncFindOp.GetAddressOf()
);
// Registers completed callback
hr = asyncFindOp->put_Completed(asyncFindCb.Get());
// Waits for enumeration to complete before continuing
WaitForSingleObjectEx(findEvent.Get(), INFINITE, FALSE);
// Retrieves the result from the asynchronous call
ComPtr<IVectorView<DeviceInformation*>> devColl;
hr = asyncFindOp->GetResults(devColl.GetAddressOf());
// Checks for collection size
unsigned int collSize;
hr = devColl->get_Size(&collSize);
if (collSize == 0) {
return nullptr;
}
// Retrieves the first DeviceInformation object from the collection
ComPtr<IDeviceInformation> devInfo;
hr = devColl->GetAt(0, devInfo.GetAddressOf());
// Retrieves the device's id
HString devId;
hr = devInfo->get_Id(devId.GetAddressOf());
此外,我确实初始化WinRT,通过这种方式:
RoInitializeWrapper initialize(RO_INIT_MULTITHREADED);
if (FAILED(initialize)) return nullptr;
*为简洁起见,删除了多个if (FAILED(hr)) return nullptr;
。
GetLastError function
检索调用线程的最后一个错误代码值
最后一个错误代码以每个线程为基础进行维护
多个线程不会覆盖彼此的最后一个错误代码。
但我尝试传递一个常量字符串(我知道这是正确的),结果是一样的。
ERROR_INVALID_HANDLE
调用方在InterfaceHandle参数中传递了NULL。
如上所述,您必须从HRESULT
中获得结果
[&openEvent](IAsyncOperation<UsbDevice*> *opHandler, AsyncStatus status) -> HRESULT
我会尝试循环浏览集合,找出如何从中获得错误
https://msdn.microsoft.com/en-us/library/windows/apps/windows.devices.enumeration.deviceinformationcollection.indexof
- 如何解决"invalid conversion from 'char' to 'const char*'"
- 如何处理 c++ 中类实现中的"invalid use of non-static data member"?
- <Windows>为什么 std::thread::native_handle 返回类型为"long long unsigned int"的值,而不是 void*(又名 HANDLE)?
- C++ "error: invalid use of void expression"
- 收到错误"invalid use of non-static data member 'stu::n' "
- Poloniex API "Invalid command" c++ libcurl
- C++模板错误:"invalid explicitly-specified argument for template parameter"
- SDL_CreateTextureFromSurface() "Invalid texture"错误?
- C++ "Invalid use of 'this' in non-member function" ,
- protobuf C++ SQLite handle blob data
- 为什么gmp会在这里与"invalid next size"重新定位一起崩溃?
- 继承类时"invalid use of incomplete type ‘class tree_node_t’"
- 为什么我会"Invalid read of size 8"?(瓦尔格林德)
- "fast"或"normal"在"free(): invalid next size (fast)"中是什么意思?
- 如何在Arduino程序中解决"invalid operands of types"?
- C++ libtins "An invalid handle was specified"
- 尝试执行任何需要它的操作时,无法修复 WinAPI 中的"invalid handle"错误
- 在没有 UWP 的情况下从 C++/WinRT 使用 FileOpenPicker 时出现视觉"Invalid window handle"错误
- WSARecv 有时会返回与 IOCP 端口关联的套接字的"invalid handle (error no 6)"。(C++)
- 为什么我在调用 GetThreadTimes 时收到错误"The handle is invalid"?