none
WMI rs232 event watcher stopped, but wmi keeps opening and closing com ports RRS feed

  • Question

  • I am not sure this is the right forum, but here goes>

    I am using WMI to create an event listener to be notified when a USB rs232 com port is yanked, or the device loses power.

    I have to do this so I can close the port before the cable is reinserted or the device boots up again, because if I don't, it seems the serial port class in .net keeps a handle around, so that the device will fail to register again as a USB rs232 com port device.

    Everything is working happy case, but I have some problems with running tests over time.  Eventually, an Open() call will fail, because wmiprsve.exe keeps opening and closing the com ports.

    I have tried in my Close() call to stop and dispose the event watchers, but wmi is hanging around, opening and closing all com ports like mad.

    My question is, how do I tell WMI to stop monitoring the COM ports, if the Stop() and Dispose() on the event watchers is not enough?

    Code

    //To start listening for com port removal and creation:
    
          WqlEventQuery q = new WqlEventQuery();
          q.EventClassName = "__InstanceCreationEvent";
          q.Condition = "TargetInstance ISA 'Win32_SerialPort'";
          q.WithinInterval = TimeSpan.FromSeconds(1);
          _watcherCreation = new ManagementEventWatcher(q);
          _watcherCreation.EventArrived += new EventArrivedEventHandler(watcherCreation_EventArrived);
          _watcherCreation.Start();
    
          q.EventClassName = "__InstanceDeletionEvent";
          q.Condition = "TargetInstance ISA 'Win32_SerialPort'";
          q.WithinInterval = TimeSpan.FromSeconds(1);
          _watcherRemoval = new ManagementEventWatcher(q);
          _watcherRemoval.EventArrived += new EventArrivedEventHandler(watcherRemoval_EventArrived);
          _watcherRemoval.Start();
    
    
    //When I wish to quit listening:
    // this is apparently not enough to stop WMI from opening and closing ports
                _watcherCreation.Stop();
                _watcherCreation.Dispose();
                _watcherRemoval.Stop();
                _watcherRemoval.Dispose();
    
    Tuesday, January 11, 2011 11:14 AM

Answers

  • WMI responds to system events long after they occur.  Writing code to respond to these events is dangerous because of the delay.  Trash WMI and use the solution in the thread  "serialport unplug plug, johnwein".  Copy and paste the quoted words in the Bing box at the top of this page.
    • Marked as answer by HalfAsleep Monday, January 17, 2011 2:30 PM
    Tuesday, January 11, 2011 3:46 PM
  • The referenced thread covers your question in detail.  Particularly the problem with WMI.  Typically, you'll get direct notification,  either a timeout or an error, long before any notification from WMI.  The thread covers most of the ways you can handle the disconnection problem.  You can also register for notification of device removal and and arrival if you don't have a window.
    • Marked as answer by HalfAsleep Monday, January 17, 2011 2:29 PM
    Thursday, January 13, 2011 9:05 AM
  • I managed to get a bit further myself in this thread:

    http://social.msdn.microsoft.com/Forums/en/netfxbcl/thread/abc806ff-42e4-4c60-aa96-3939fdb420c1

    I feel John's thread is about slightly different problems, but both of them together should be helpful to anyone wondering about USB rs232 ports.

    • Marked as answer by HalfAsleep Monday, January 17, 2011 2:29 PM
    Monday, January 17, 2011 2:29 PM

All replies

  • WMI responds to system events long after they occur.  Writing code to respond to these events is dangerous because of the delay.  Trash WMI and use the solution in the thread  "serialport unplug plug, johnwein".  Copy and paste the quoted words in the Bing box at the top of this page.
    • Marked as answer by HalfAsleep Monday, January 17, 2011 2:30 PM
    Tuesday, January 11, 2011 3:46 PM
  • That thread was very long and I had some trouble just picking out what exactly was the solution.  Any more information greatly appreciated.

    As additional information, I can also inform that the usb rs232 device is not constantly generating traffic and there is no need to have real time performance.  As long as I perform SerialPort.Close() before the USB device powers up after a reboot, I am ok.

    My code is an assembly that facilitates communication with this device without having to implement out link layer protocol.  The client application performs an Open call on my assembly at start and leaves it open usually until the application closes as well.

    My need then is to perform a "background" close and open as the usb device disappears and reappears, so that the client application does not have to worry about the USB device rebooting etc.

    Does anyone have any advice on where else to post questions about WMI or some other way of handling usb rs232 serial ports in .net and or COM?

    Thank you.

    Wednesday, January 12, 2011 7:49 AM
  • I would also love to know why WMI does not stop when I am done and stopping my wmi event watcher, regardless if I end up using WMI or not.  It frustrates me that it keeps going after I am done with it.  My solution now works great, except that WMI keeps going after I have stopped it.  This gives me a headache when the client application again performs an open, as I may risk not being able to open the COM port, if I open it the exact same time WMI is "polling" it to see if it is there.
    Wednesday, January 12, 2011 7:52 AM
  • John, could you please give me some description as to how to solve it?  The other thread is very large, please give me some pointers as to what is the solution.
    Thursday, January 13, 2011 8:14 AM
  • John, could you please give me some description as to how to solve it?  The other thread is very large, please give me some pointers as to what is the solution.

    The solution is the post marked as answer.  The other solution is to use the .NET 4.0 SerialPort which has corrected the problem.
    Thursday, January 13, 2011 8:27 AM
  • The solution marked as the answer indicates how to treat a close that goes wrong on a port that is already missing? 

    I also need to know that the device is "gone" and perform a close at that time.  Does that involve the WndProc override that is briefly mentioned in that thread?  How do I actually discover that the port is gone?  I can't tell from the other thread how you have actually discovered that it is gone.

    My assembly does not have any forms or windows, so how in that case do I override the WndProc?

    Thanks

    Thursday, January 13, 2011 8:51 AM
  • The referenced thread covers your question in detail.  Particularly the problem with WMI.  Typically, you'll get direct notification,  either a timeout or an error, long before any notification from WMI.  The thread covers most of the ways you can handle the disconnection problem.  You can also register for notification of device removal and and arrival if you don't have a window.
    • Marked as answer by HalfAsleep Monday, January 17, 2011 2:29 PM
    Thursday, January 13, 2011 9:05 AM
  • I managed to get a bit further myself in this thread:

    http://social.msdn.microsoft.com/Forums/en/netfxbcl/thread/abc806ff-42e4-4c60-aa96-3939fdb420c1

    I feel John's thread is about slightly different problems, but both of them together should be helpful to anyone wondering about USB rs232 ports.

    • Marked as answer by HalfAsleep Monday, January 17, 2011 2:29 PM
    Monday, January 17, 2011 2:29 PM
  • I looked at your other thread and it seems to me that all the threads referenced address the same problem.  Here's example code to detect the connection and disconnection of a SerialPort:

    using System;
    using System.Runtime.InteropServices;
    using System.IO.Ports;
    using System.Text;
    using System.Windows.Forms;

    namespace WindowsFormsApplication1
    {
      
    public partial class Form1 : Form
      {
        
    private TextBox TB = new TextBox();
        
    private Timer Tmr = new Timer();
        
    public Form1()
        {
          InitializeComponent();
          TB.Multiline = 
    true;
          TB.Dock = 
    DockStyle.Fill;
          TB.Parent = 
    this;
          
    string[] portNames = SerialPort.GetPortNames();
          
    int i;
          
    for (i = 0; i < portNames.Length; i++)
            
    if (portNames[i] == serialPort1.PortName) break;
          
    if (i < portNames.Length) OpenPort(); else ClosePort();
        }
        
    protected override void WndProc(ref System.Windows.Forms.Message m)
        {
          
    base.WndProc(ref m);
          
    if (m.Msg == 0X219)
          {
            
    int WParam = m.WParam.ToInt32();
            
    if ((WParam & 0X8000) == 0X8000)
            {
              
    int Len = Marshal.ReadInt32(m.LParam);
              
    if (Marshal.ReadInt32(m.LParam, 4) == 3)
              {
                
    StringBuilder SB = new StringBuilder();
                
    for (int I = 12; I < Len; I += 2)
                {
                  SB.Append((
    char)(Marshal.ReadByte(m.LParam, I)));
                }
                
    if ((SB.ToString()).Substring(0, 4) == serialPort1.PortName)
                {
                  
    int ArriveDepart = (WParam & 0XFFF);
                  
    if (ArriveDepart == 0)
                    OpenPort();
                  
    else if (ArriveDepart == 4)
                    ClosePort();
                }
              }
            }
          }
        }
        
    public void OpenPort()
        {
          TB.Text = 
    "Connected" + Environment.NewLine;
          serialPort1.Open();
        }
        
    public void ClosePort()
        {
          TB.Text = 
    "Disconnected" + Environment.NewLine;
          
    if (serialPort1.IsOpen)
          {
            
    try
            {
              serialPort1.Close();
            }
            
    catch (Exception Ex)
            {
              
    Console.WriteLine(Ex.Message);
            }
          }
        }
      }
    }

    Monday, January 17, 2011 4:28 PM