尝试访问USB设备时RPC_E_CANTCALLOUT_ININPUTSYNCCALL

时间:2014-05-04 09:00:44

标签: c# windows exception

我有这段代码:

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

我收到此错误:

由于应用程序正在调度输入同步调用,因此无法进行传出呼叫。 (来自HRESULT的异常:0x8001010D(RPC_E_CANTCALLOUT_ININPUTSYNCCALL))。

如果我将thread.sleep(5000)置于上面的代码之上,那么它在执行前等待5秒,然后代码就可以了。因此,冲突必须在某个地方,其他事情首先尝试访问该设备并将其全部用于自己。

我搜索了互联网并发现了一些建议,例如向我自己发送自定义postmessage以触发代码,但我对如何做到这一点几乎没有任何想法,甚至如何解决问题。

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

1 个答案:

答案 0 :(得分:2)

将代码包装在新线程中:

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