rpc_e_cantcallout_ininputsyncall当尝试访问USB设备

本文关键字:访问 设备 USB cantcallout ininputsyncall rpc | 更新日期: 2023-09-27 18:01:39

我有这段代码:

var searcher = new ManagementObjectSearcher("root''CIMV2", "SELECT * FROM Win32_DiskDrive");              
foreach (var queryObj in searcher.Get().Cast<ManagementObject>()) //Error points to this line

基本上这段代码所做的是,它运行一个连接的设备列表,并查看我想要的设备是否已连接。如果我在运行代码时设备已经连接的情况下运行此代码,那么它将完美地工作。但是,如果我用DBT_DEVICEARRIVAL(这是系统在某些设备连接时发送的事件)触发此代码,并使用

捕获它
private static IntPtr WndProc(IntPtr hwnd, int msg, IntPtr wParam, IntPtr lParam, ref bool handled)
{
    if(..DBT_DEVICEARRIVAL..) 
        new ScanDevices(); /*Here lies the code from above (in the class)*/
}

我得到这个错误:

由于应用程序正在调度输入同步调用,因此不能进行传出调用。(Exception from HRESULT: 0x8001010D (RPC_E_CANTCALLOUT_ININPUTSYNCCALL)).

如果我把thread.sleep(5000)放在上面的代码上面,那么它在执行前等待5秒,那么代码就可以工作了。所以冲突一定是在某个地方,在那里其他东西试图首先访问该设备并独占它。

我搜索了互联网,发现了一些建议,比如向自己发送自定义postmessage来触发代码,但我不知道如何做到这一点,甚至不知道如何解决这个问题。

这里最好的解决方案是什么?

rpc_e_cantcallout_ininputsyncall当尝试访问USB设备

在新线程中封装代码:

Thread thread = new Thread(() =>
{
    ManagementObjectSearcher theSearcher = new ManagementObjectSearcher("SELECT * FROM Win32_DiskDrive");
    foreach (ManagementObject currentObject in theSearcher.Get())
    {
        Debug.WriteLine("Device present: " + currentObject);          
        ManagementObject theSerialNumberObjectQuery = new ManagementObject("Win32_PhysicalMedia.Tag='" + currentObject["DeviceID"] + "'");
        serial = theSerialNumberObjectQuery["SerialNumber"].ToString();
    }
});
thread.Start();
thread.Join(); //wait for the thread to finish