2016-08-06 3 views
0

Я разрабатываю программу, использующую аппаратное обеспечение (я использую Arduino) для сбора данных и хранения данных в базе данных. Поскольку нет способа убедиться, что serialport получает данные, я пытаюсь реализовать фрагмент кода, чтобы объявить удаление оборудования, а затем проверить, есть ли мое устройство, которое все еще подключено или иным образом информирует пользователя. То, что я пришел до сих пор является:Как узнать, удалено ли какое-либо устройство C#

protected override void WndProc(ref Message m) 
    { 
     base.WndProc(ref m); 

     switch (m.Msg) 
     { 
      case WM_DEVICECHANGE: 
       switch ((int)m.WParam) 
       { 
        case DBT_DEVICEARRIVAL: 
         listBox1.Items.Add("New Device Arrived"); 
         int devType = Marshal.ReadInt32(m.LParam, 4); 
         if (devType == DBT_DEVTYP_PORT) 
         { 
          string portName = Marshal.PtrToStringAuto((IntPtr)((long)m.LParam + 12)); 
          listBox1.Items.Add("the name of the port is " + portName); 
         } 

         break; 

        case DBT_DEVICEREMOVECOMPLETE: 
         { 
          listBox1.Items.Add("Device Removed"); 

         } 

         break; 
       } 
       break; 
     } 
    } 

который сообщает мне, если какие-либо изменения в подключении устройства к компьютеру произошло. Кроме того, следующий код говорит мне о существовании Arduino в списке подключенных устройств:

ManagementScope connectionScope = new ManagementScope(); 
     SelectQuery serialQuery = new SelectQuery("SELECT * FROM Win32_SerialPort"); 
     ManagementObjectSearcher searcher = new ManagementObjectSearcher(connectionScope, serialQuery); 

     try 
     { 
      foreach (ManagementObject item in searcher.Get()) 
      { 
       string desc = item["Description"].ToString(); 
       string deviceId = item["DeviceID"].ToString(); 

       if (!desc.Contains("Arduino")) 
       { 
        // Inform the user about the disconnection of the arduino 
       } 
      } 
     } 
     catch //(ManagementException e) 
     { 
      /* Do Nothing */ 
     } 

Как всегда, когда я смешиваю коды, чтобы сообщить мне, когда Arduino отключен, они не соответствуют друг другу и бросок ошибка:

Transition into COM context 0x8ff990 for this RuntimeCallableWrapper failed with the following error: An outgoing call cannot be made since the application is dispatching an input-synchronous call. (Exception from HRESULT: 0x8001010D (RPC_E_CANTCALLOUT_ININPUTSYNCCALL)). This is typically because the COM context 0x8ff990 where this RuntimeCallableWrapper was created has been disconnected or it is busy doing something else and cannot process the context transition. No proxy will be used to service the request on the COM component and calls will be made to the COM component directly. This may cause corruption or data loss. To avoid this problem, please ensure that all COM contexts/apartments/threads stay alive and are available for context transition, until the application is completely done with the RuntimeCallableWrappers that represents COM components that live inside them. 

Любая помощь приветствуется, заблаговременно.

PS: Для вашей дополнительной информации, все закодировано является:

protected override void WndProc(ref Message m) 
    { 
     base.WndProc(ref m); 

     switch (m.Msg) 
     { 
      case WM_DEVICECHANGE: 
       switch ((int)m.WParam) 
       { 
        case DBT_DEVICEARRIVAL: 
         listBox1.Items.Add("New Device Arrived"); 
         int devType = Marshal.ReadInt32(m.LParam, 4); 
         if (devType == DBT_DEVTYP_PORT) 
         { 
          string portName = Marshal.PtrToStringAuto((IntPtr)((long)m.LParam + 12)); 
          listBox1.Items.Add("the name of the port is " + portName); 
         } 

         break; 

        case DBT_DEVICEREMOVECOMPLETE: 
         { 
          listBox1.Items.Add("Device Removed"); 
          ManagementScope connectionScope = new ManagementScope(); 
          SelectQuery serialQuery = new SelectQuery("SELECT * FROM Win32_SerialPort"); 
          ManagementObjectSearcher searcher = new ManagementObjectSearcher(connectionScope, serialQuery); 

          try 
          { 
           foreach (ManagementObject item in searcher.Get()) 
           { 
            string desc = item["Description"].ToString(); 
            string deviceId = item["DeviceID"].ToString(); 

            if (desc.Contains("Arduino")) 
            { 
             MessageBox.Show(deviceId); 
            } 
           } 
          } 
          catch //(ManagementException e) 
          { 
           /* Do Nothing */ 
          } 
         } 

         break; 
       } 
       break; 
     } 
    } 
+0

Не достаточно действительно информации так что моя догадка, что вы нарушаете некоторые правила многопоточности. Трудно сказать, не видя кода инициализации, как вы регистрируете WndProc и т. Д. Кроме того, у вас может быть внутреннее исключение, которое более подробно объясняет, что происходит. –

ответ

0
public partial class Form1 : Form 
{ 
    ManagementEventWatcher watcher; 

    // Not all arduinos have 'Arduino' in their serialport driver 'Description', So check for a Com port Number. 
    private static string MustHavePort = "COM3"; //Port to check for. 

    public Form1() 
    { 
     InitializeComponent(); 

     watcher = new ManagementEventWatcher("SELECT * FROM Win32_DeviceChangeEvent WHERE EventType = 2 or EventType = 3"); 
     watcher.EventArrived += new EventArrivedEventHandler(USBChangedEvent); 
     watcher.Start(); 
    } 

    public void USBChangedEvent(object sender, EventArrivedEventArgs e) 
    { 
     (sender as ManagementEventWatcher).Stop(); 

     this.Invoke((MethodInvoker)delegate 
     { 
      ManagementObjectSearcher deviceList = new ManagementObjectSearcher("Select Name, Description, DeviceID from Win32_SerialPort"); 

      // List to store available USB serial devices plugged in. (Arduino(s)/Cell phone(s)). 
      List<String> ComPortList = new List <String>(); 

      listBox1.Items.Clear(); 
      textBox1.Text = ""; 
      // Any results? There should be! 
      if (deviceList != null) 
      { 
       // Enumerate the devices 
       foreach (ManagementObject device in deviceList.Get()) 
       { 
        string SerialPortNumber = device["DeviceID"].ToString(); 
        string serialName = device["Name"].ToString(); 
        string SerialDescription = device["Description"].ToString(); 
        ComPortList.Add(SerialPortNumber); 
        listBox1.Items.Add(SerialPortNumber); 
        listBox1.Items.Add(serialName); 
        listBox1.Items.Add(SerialDescription); 
       } 
      } 
      else 
      { 
       listBox1.Items.Add("NO SerialPorts AVAILABLE!"); 
       // Inform the user about the disconnection of the arduino ON PORT 3 etc... 
       SendAlarm(); 
      } 

      if (!ComPortList.Contains(MustHavePort)) 
      { 
       // Inform the user about the disconnection of the arduino ON PORT 3 etc... 
       SendAlarm(); 
      } 

     }); 
     (sender as ManagementEventWatcher).Start(); 
    } 

    private void SendAlarm() 
    { 
     textBox1.Text = "Alarm..." + MustHavePort + "Port Missing..."; 
     MessageBox.Show("Error " + MustHavePort + " Port Missing!!!", "Serial Port Error."); 
    } 

    private void Form1_FormClosing(object sender, FormClosingEventArgs e) 
    { 
     watcher.Stop(); 
    } 
} 
Смежные вопросы