【问题标题】:Detecting USB to RS232 converter when connecting or disconnected连接或断开连接时检测 USB 到 RS232 转换器
【发布时间】:2016-06-28 15:38:57
【问题描述】:

经过一番摸索,我设法在我的系统上找到了 USB 到 RS232 转换器的 com 端口号。我在当前系统中有 15 个。 我现在需要做的是检测一个连接或断开连接,以便我可以更新我的表。我可以弄清楚如何检测 USB 存储设备,但同样不适用于 USB 到 RS232 转换器。请问有谁知道我如何检测到这一点?

这是我用来计算转换器使用的 com 端口的代码 sn-p

private void btn_tst2_Click(object sender, EventArgs e)
{          
    ManagementObjectSearcher searcher = new ManagementObjectSearcher("root\\CIMV2",
    "SELECT * FROM Win32_PnPEntity WHERE ClassGuid=\"{4d36e978-e325-11ce-bfc1-08002be10318}\"");

    foreach (ManagementObject queryObj in searcher.Get())
    {
        rtxbx_output.AppendText(queryObj["Name"].ToString() +"\r");
    }

}

【问题讨论】:

  • 我需要知道的是,当您插入 USB 时,而不是端口号。上面的代码为我找到了端口号,但我至今无法知道 USB 何时插入。

标签: c# serial-port usb wmi


【解决方案1】:

你可以做一些线程或任务来查询从方法System.IO.Ports.SerialPort.GetPortNames()返回的数组:当这个数组发生变化,或者添加了一个新元素时,就意味着一个新的串口已经连接到系统。

当然,它会返回您系统上的每个串口,但是您可以使用您的代码 sn-p 选择其中哪些是 USB-RS232 转换器。

【讨论】:

    【解决方案2】:

    你可以使用MSSerial_PortName请找sn-p。

    注意:这不是一个有效的代码,您必须根据您的要求进行更改。

    private void btn_tst2_Click(object sender, EventArgs e)
            {   
    // connection to WMI rather than cimv2 namespace       
                ManagementObjectSearcher searcher = new ManagementObjectSearcher("root\\WMI",
                "select * from MSSerial_PortName");
    
                foreach (ManagementObject queryObj in searcher.Get())
                {
                   queryObj["Active"]; // status
                   queryObj["InstanceName"];  
                   queryObj["PortName"]; // port number
                }
    
            }
    

    【讨论】:

    • 谢谢,但要完成这项工作,我发现您必须以管理员身份运行。然后它将提供端口号,就像我的原始代码一样,无需以管理员身份运行即可工作。这仍然给我带来了不知道何时插入或移除 USB 到 RS232 的问题,这是我现在正在尝试做的。如果它是硬盘驱动器,我可以得到它,如果它是 USB 到 RS232 设备,有什么想法吗?
    • 是的,你是对的,它必须是管理员。但是您是否无法通过 queryObj["Active"]; 获得正确的状态。我建议使用 wbemtest 来进行插拔和检查状态。
    【解决方案3】:

    在经历了很多挫折之后,我终于弄清楚了如何实现我所需要的。我发布答案,以防它指向将来困在同一区域的任何人。我在代码中包含了 cmets。我最后得到的是所有 Com 端口的列表,当一个人离开或加入时,它会刷新。在您的 PC 上可以找到文件 dbt.h。

    要使下面的代码正常工作,只需使用富文本框和两个按钮制作一个解决方案。

        using System;
        using System.Collections.Generic;
        using System.ComponentModel;
        using System.Data;
        using System.Drawing;
        using System.Linq;
        using System.Text;
        using System.Threading.Tasks;
        using System.Windows.Forms;
        using System.Management;    //used to perform WMI queries
        using System.Threading;
        using System.Runtime.InteropServices; // needed for marshalling
    
        namespace MissionControl
        {
            public partial class Control : Form
            {
                public Control()
                {
                    InitializeComponent();
                }
    
                // WndProc = Window Procedures: Every window has an associated     window procedure — a function that processes all messages sent 
            // or posted to all windows of the class. All aspects of a window's appearance and behavior depend on the window procedure's 
            // response to these messages. see https://msdn.microsoft.com/en-us/library/ms632593%28v=vs.85%29.aspx
            protected override void WndProc(ref Message m)
            {
                //you may find these definitions in dbt.h 
                const int WM_DEVICECHANGE = 0x0219; // in dbt.h, BroadcastSpecialMessage constants. 
                const int DBT_DEVICEARRIVAL = 0x8000;  // system detected a device arrived see dbt.h
                const int DBT_DEVICEREMOVECOMPLETE = 0x8004; //system detected a device removal see dbt.h
                const int DBT_DEVTYP_PORT = 0x00000003;  // serial, parallel in dbt.h
    
                switch (m.Msg)
                {
                    case WM_DEVICECHANGE:
                        switch (m.WParam.ToInt32())
                        {
                            case DBT_DEVICEARRIVAL:
                                {
                                    // Get the DBT_DEVTYP* as defined in dbt.h
                                    // We are looking for DBT_DEVTYP_PORT value = 3 which is Serial port
                                    int devTypeA = Marshal.ReadInt32(m.LParam, 4);
    
                                    if (devTypeA == DBT_DEVTYP_PORT)
                                    {
                                        rchtxbx_output.SelectedText = string.Empty;
                                        rchtxbx_output.SelectionFont = new Font(rchtxbx_output.SelectionFont, FontStyle.Bold);
                                        rchtxbx_output.SelectionColor = Color.Lime;
                                        rchtxbx_output.AppendText("\rSerial Port Connected\r\rList of Current Ports\r");
    
                                    }
                                    else
                                    {
                                        // We should never get in here but just in case do somethign rather than fall over
                                        rchtxbx_output.SelectedText = string.Empty;
                                        rchtxbx_output.SelectionFont = new Font(rchtxbx_output.SelectionFont, FontStyle.Bold);
                                        rchtxbx_output.SelectionColor = Color.Red;
                                        rchtxbx_output.AppendText("Non-Serial Port Connected\r");
                                    }
    
    
                                    //To prevent cross threading we will start the function call in its own thread
                                    // Create the thread object, passing in GetPortNum
                                    //ThreadA is the arrival thread (just connected)
                                    Thread ThreadA = new Thread(new ThreadStart(GetPortNum));
    
                                    // Start the thread via a ThreadStart delegate
                                    ThreadA.Start();
    
                                }
                                break;
                            case DBT_DEVICEREMOVECOMPLETE:
                                {
                                    // Get the DBT_DEVTYP* as defined in dbt.h
                                    // We are looking for DBT_DEVTYP_PORT value = 3 which is Serial port
                                    int devTypeD = Marshal.ReadInt32(m.LParam, 4);
    
                                    if (devTypeD == DBT_DEVTYP_PORT)
                                    {
                                        rchtxbx_output.SelectedText = string.Empty;
                                        rchtxbx_output.SelectionFont = new Font(rchtxbx_output.SelectionFont, FontStyle.Bold);
                                        rchtxbx_output.SelectionColor = Color.Lime;
                                        rchtxbx_output.AppendText("\rSerial Port Disconnected\r\rList of Current Ports\r");
                                    }
                                    else
                                    {
                                        // We should never get in here but just in case do something rather than fall over
                                        rchtxbx_output.SelectedText = string.Empty;
                                        rchtxbx_output.SelectionFont = new Font(rchtxbx_output.SelectionFont, FontStyle.Bold);
                                        rchtxbx_output.SelectionColor = Color.Red;
                                        rchtxbx_output.AppendText("Non-Serial Port Disconneted\r");
    
                                    }
    
                                    //To prevent cross threading we will start the function call in its own thread
                                    // Create the thread object, passing in GetPortNum
                                    //ThreadD is the departure thread (disconnected) 
                                    Thread ThreadD = new Thread(new ThreadStart(GetPortNum));
    
                                    // Start the thread via a ThreadStart delegate
                                    ThreadD.Start();
                                }
    
                                break;
                        }
    
                        break;
                }
                //we detect the media arrival event 
                base.WndProc(ref m);
            }
    
    
            private void btn_close_Click(object sender, EventArgs e)
            {
                this.Close();
            }
    
            private void btn_clr_Click(object sender, EventArgs e)
            {
                rchtxbx_output.Clear();
            }
    
            private void GetPortNum()
            {
                //Windows Management Instrumentation (WMI) consists of a set of extensions to the Windows Driver Model that provides an 
                //operating system interface through which instrumented components provide information and notification. 
                // To work out the WMI to use, get the tool https://www.microsoft.com/en-us/download/details.aspx?id=8572
    
                //GUID (or UUID) is an acronym for 'Globally Unique Identifier' (or 'Universally Unique Identifier'). It is a 128-bit 
                //integer number used to identify resources. The term GUID is generally used by developers working with Microsoft 
                //technologies, while UUID is used everywhere else.
                // Get the list of ClassGUID from https://msdn.microsoft.com/en-us/library/windows/hardware/ff553426%28v=vs.85%29.aspx
    
                string comportnum = "";
                int textStart = 0;
                char[] textEnd = { ')' };
    
    
                ManagementObjectSearcher searcher = new ManagementObjectSearcher("root\\CIMV2",
                        "SELECT * FROM Win32_PnPEntity WHERE ClassGuid=\"{4d36e978-e325-11ce-bfc1-08002be10318}\"");
                foreach (ManagementObject queryObj in searcher.Get())
                {
                    comportnum = queryObj["Name"].ToString(); // Get the name of the comm port
    
                    //Format the string to extract the comport number only
                    textStart = comportnum.IndexOf("(COM");
                    comportnum = comportnum.Remove(0, textStart + 4).TrimEnd(textEnd);
    
                    //To prevent cross threading use Invoke. We are writing to a control created in another thread.
                    rchtxbx_output.Invoke(new EventHandler(delegate
                    {
                        rchtxbx_output.SelectedText = string.Empty;
                        rchtxbx_output.SelectionFont = new Font(rchtxbx_output.SelectionFont, FontStyle.Bold);
                        rchtxbx_output.SelectionColor = Color.Lime; //set font colour
                        rchtxbx_output.AppendText("Comm Port = " + comportnum + "\r"); //add some text
                        rchtxbx_output.ScrollToCaret(); // move cursor to the end
                    }));
                }
            }
        }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-03-16
      • 1970-01-01
      • 2015-09-03
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多