尝试访问USB设备时,RPC_E_CANTCALLOUT_ININPUTSYNCCALL

我有这段代码:

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)*/} 

)我得到这个错误:

由于应用程序正在调度input同步调用,因此不能进行传出调用。 (从HRESULTexception:0x8001010D(RPC_E_CANTCALLOUT_ININPUTSYNCCALL))。

如果我把thread.sleep(5000)放在上面的代码之上,所以它在执行前等待5秒钟,然后代码工作。 所以冲突一定是在某个地方,其他的事情先试着去访问这个设备,然后把所有的东西都给自己。

我search了互联网,发现了一些build议,比如发送自定义的postmessage来触发代码,但是我不知道怎么做,甚至怎么解决这个问题。

这里最好的解决scheme是什么?

用新的线程包装你的代码:

 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