连接或断开时检测 USB 到 RS232 转换器
Detecting USB to RS232 converter when connecting or disconnected
经过一番摸索,我设法找到了我系统上 USB 到 RS232 转换器的 com 端口号。我在当前系统中有 15 个。 我现在需要做的是检测何时连接或断开连接,以便我可以更新我的table。我可以弄清楚如何检测 USB 存储设备,但同样不适用于 USB 到 RS232 转换器。有人知道我如何检测到这个吗?
这是我用来计算转换器使用的 com 端口的代码片段
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");
}
}
您可以创建某种线程或任务来查询return从方法System.IO.Ports.SerialPort.GetPortNames()
编辑的数组:当这个数组发生变化,或者添加了一个新元素时,这意味着一个新的串口已连接到系统
当然,它会 return 您系统上的每个串行端口,但是您可以使用您的代码片段选择其中哪些是 USB-RS232 转换器。
您可以使用 MSSerial_PortName
请找到代码段。
注意:这不是工作代码,您必须根据您的要求进行更改。
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
}
}
在经历了很多挫折之后,我终于弄清楚了如何实现我所需要的。我 post 的答案,以防它为将来卡在同一区域的任何人提供一个指针。我在代码中包含注释。我最后得到的是所有 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
}));
}
}
}
}
经过一番摸索,我设法找到了我系统上 USB 到 RS232 转换器的 com 端口号。我在当前系统中有 15 个。 我现在需要做的是检测何时连接或断开连接,以便我可以更新我的table。我可以弄清楚如何检测 USB 存储设备,但同样不适用于 USB 到 RS232 转换器。有人知道我如何检测到这个吗?
这是我用来计算转换器使用的 com 端口的代码片段
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");
}
}
您可以创建某种线程或任务来查询return从方法System.IO.Ports.SerialPort.GetPortNames()
编辑的数组:当这个数组发生变化,或者添加了一个新元素时,这意味着一个新的串口已连接到系统
当然,它会 return 您系统上的每个串行端口,但是您可以使用您的代码片段选择其中哪些是 USB-RS232 转换器。
您可以使用 MSSerial_PortName
请找到代码段。
注意:这不是工作代码,您必须根据您的要求进行更改。
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
}
}
在经历了很多挫折之后,我终于弄清楚了如何实现我所需要的。我 post 的答案,以防它为将来卡在同一区域的任何人提供一个指针。我在代码中包含注释。我最后得到的是所有 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
}));
}
}
}
}