使用Visual Studio 编写C#程序(独立模块)
一、扫描端口
1、静态扫描使用的所有端口,窗口显示第一个端口号
private void PortNameComboBox_MouseClick(object sender, MouseEventArgs e)
{
PortNameComboBox.Items.Clear();
//列出可用的端口
string[] ports = SerialPort.GetPortNames();
foreach (string port in ports)
{
PortNameComboBox.Items.Add(port);
}
// 显示第一个端口号
if (PortNameComboBox.Items.Count > 0)
{
PortNameComboBox.SelectedIndex = 0;
}
}
显示效果
2、根据条件挑出仅为CH340串口的端口
using System.Management; // 需要添加引用System.Management
/// <summary>
/// 枚举win32 api
/// </summary>
public enum HardwareEnum
{
// 硬件
Win32_Processor, // CPU 处理器
Win32_PhysicalMemory, // 物理内存条
Win32_Keyboard, // 键盘
Win32_PointingDevice, // 点输入设备,包括鼠标。
Win32_FloppyDrive, // 软盘驱动器
Win32_DiskDrive, // 硬盘驱动器
Win32_CDROMDrive, // 光盘驱动器
Win32_BaseBoard, // 主板
Win32_BIOS, // BIOS 芯片
Win32_ParallelPort, // 并口
Win32_SerialPort, // 串口
Win32_SerialPortConfiguration, // 串口配置
Win32_SoundDevice, // 多媒体设置,一般指声卡。
Win32_SystemSlot, // 主板插槽 (ISA & PCI & AGP)
Win32_USBController, // USB 控制器
Win32_NetworkAdapter, // 网络适配器
Win32_NetworkAdapterConfiguration, // 网络适配器设置
Win32_Printer, // 打印机
Win32_PrinterConfiguration, // 打印机设置
Win32_PrintJob, // 打印机任务
Win32_TCPIPPrinterPort, // 打印机端口
Win32_POTSModem, // MODEM
Win32_POTSModemToSerialPort, // MODEM 端口
Win32_DesktopMonitor, // 显示器
Win32_DisplayConfiguration, // 显卡
Win32_DisplayControllerConfiguration, // 显卡设置
Win32_VideoController, // 显卡细节。
Win32_VideoSettings, // 显卡支持的显示模式。
// 操作系统
Win32_TimeZone, // 时区
Win32_SystemDriver, // 驱动程序
Win32_DiskPartition, // 磁盘分区
Win32_LogicalDisk, // 逻辑磁盘
Win32_LogicalDiskToPartition, // 逻辑磁盘所在分区及始末位置。
Win32_LogicalMemoryConfiguration, // 逻辑内存配置
Win32_PageFile, // 系统页文件信息
Win32_PageFileSetting, // 页文件设置
Win32_BootConfiguration, // 系统启动配置
Win32_ComputerSystem, // 计算机信息简要
Win32_OperatingSystem, // 操作系统信息
Win32_StartupCommand, // 系统自动启动程序
Win32_Service, // 系统安装的服务
Win32_Group, // 系统管理组
Win32_GroupUser, // 系统组帐号
Win32_UserAccount, // 用户帐号
Win32_Process, // 系统进程
Win32_Thread, // 系统线程
Win32_Share, // 共享
Win32_NetworkClient, // 已安装的网络客户端
Win32_NetworkProtocol, // 已安装的网络协议
Win32_PnPEntity,//all device
}
/// <summary>
/// WMI取硬件信息
/// </summary>
/// <param name="hardType"></param>
/// <param name="propKey"></param>
/// <returns></returns>
private static string[] MulGetHardwareInfo(HardwareEnum hardType, string propKey)
{
List<string> strs = new List<string>();
try
{
using (ManagementObjectSearcher searcher = new ManagementObjectSearcher("select * from " + hardType))
{
var hardInfos = searcher.Get();
foreach (var hardInfo in hardInfos)
{
if (hardInfo.Properties[propKey].Value != null && hardInfo.Properties[propKey].Value.ToString().Contains("COM"))
{
strs.Add(hardInfo.Properties[propKey].Value.ToString());
}
}
searcher.Dispose();
}
return strs.ToArray();
}
catch
{
return strs.ToArray();
}
}
/// <summary>
/// 串口信息
/// </summary>
/// <returns></returns>
public static string[] GetSerialPort()
{
return MulGetHardwareInfo(HardwareEnum.Win32_PnPEntity, "Name");
}
private void PortNameComboBox_MouseClick(object sender, MouseEventArgs e)
{
// 清除全部端口缓存
PortNameComboBox.Items.Clear();
//列出可用的端口
string[] ports = GetSerialPort();
/*方式一
foreach (string port in ports)
{
if (port.ToString().Contains("USB")) // 筛选端口
{
// 端口显示处理,仅显示端口号,不显示全部名称
for (int i = 0; i < port.ToArray().Length; i++)
{
if (port.ToArray()[i] == 'C' && port.ToArray()[i + 1] == 'O' && port.ToArray()[i + 2] == 'M')
{
char[] name= new char[port.ToArray().Length - i -1];
Array.Copy(port.ToArray(), i, name, 0, port.ToArray().Length - i - 1);
PortNameComboBox.Items.Add(new string(name));
}
}
//也可以选择全部显示
//PortNameComboBox.Items.Add(port);
}
}*/
// 方式二
foreach (string port in ports)
{
if (port.Contains("USB") && port.Contains("COM"))
{
string[] name = port.Replace(")", "").Split('(');
PortNameComboBox.Items.Add(name[1]);
}
}
if (PortNameComboBox.Items.Count > 0)
{
PortNameComboBox.SelectedIndex = 0;
}
}
未进行名称筛选(需要比较大的显示窗口空间)
筛选CH340串口全部名称(需要比较大的显示窗口空间)
处理后显示
二、列表操作
1、列表数据接收显示到最新一条
//让文本框获取焦点
tbxRecvData.Focus();
// 文本向后添加需要使用tbxRecvData.AppendText,不要使用tbxRecvData.Text += cnt.ToString();
tbxRecvData.AppendText(cnt.ToString()\n");
2、不显示光标
// 不显示接收区的光标
[DllImport("user32", EntryPoint = "HideCaret")]
private static extern bool HideCaret(IntPtr hWnd);
private void tbxRecvData_MouseDown(object sender, EventArgs e)
{
HideCaret(this.tbxRecvData.Handle);
}
三、文件处理
1、新建文件
SaveFileDialog saveDlg = new SaveFileDialog();
saveDlg.Filter = "文本文件|*.txt";
if (saveDlg.ShowDialog() == DialogResult.OK)
{
StreamWriter sw = new StreamWriter(saveDlg.FileName);
sw.Write(tbxRecvData.Text.Replace("【yyyy-MM-dd hh:mm:ss:FFF】",""));
sw.Flush();
sw.Close();
}
2、读取文件
OpenFileDialog ofDialog = new OpenFileDialog();
ofDialog.Title = "请选择文件";
ofDialog.Filter = "文本文件(*.txt)|*.txt";
ofDialog.RestoreDirectory = true;
if (ofDialog.ShowDialog() == DialogResult.OK)
{
string fileName = ofDialog.FileName;
StreamReader sr = new StreamReader(fileName, Encoding.GetEncoding("gb2312"));
try
{
sendBuffer.Clear();
sendBuffer.AddRange(Encoding.GetEncoding("gb2312").GetBytes(sr.ReadToEnd().Replace("RECV:", "")));
sendData();
}
catch (Exception ex)
{
MessageBox.Show("发送数据失败" + ex.Message.ToString(), "错误");
}
sr.Close();
}
四、查找和显示ini文件中的参数
using System.Runtime.InteropServices; // 文件引用
using System.IO; // 文件地址调用
// 导入配置
[DllImport("kernel32")]
// 读配置文件方法的6个参数:所在的分区(section)、键值、 初始缺省值、 StringBuilder、 参数长度上限、配置文件路径
private static extern int GetPrivateProfileString(string section, string key, string deVal, StringBuilder retVal,
int size, string filePath);
[DllImport("kernel32", CharSet = CharSet.Auto)]
private static extern uint GetPrivateProfileSectionNames(IntPtr lpszReturnBuffer, uint nSize, string filePath);
/*[DllImport("kernel32")]
//写配置文件方法的4个参数:所在的分区(section)、 键值、 参数值、 配置文件路径
private static extern long WritePrivateProfileString(string section, string key, string val, string filePath);
public static void SetValue(string section, string key, string value)
{
//获得当前路径,当前是在Debug路径下
string strPath = Directory.GetCurrentDirectory() + "\\sol.ini";
WritePrivateProfileString(section, key, value, strPath);
}*/
// 获取值
public static string GetValue(string section, string key)
{
StringBuilder sb = new StringBuilder(255);
string strPath = Directory.GetCurrentDirectory() + "\\Column.ini";
//最好初始缺省值设置为非空,因为如果配置文件不存在,取不到值,程序也不会报错
GetPrivateProfileString(section, key, "", sb, 255, strPath);
return sb.ToString();
}
// 比较判断
void compare()
{
ResetDistanceTextBox.Text = GetValue(new string(distance), "L");
}
ini文件截图
// 读取显示所有分区
public static string[] ReadIniAllSectionName(string filePath)
{
uint MaxBuffer = 32767;
string[] sections = new string[0]; // 返回值
// 申请内存
IntPtr pReturnedString = Marshal.AllocCoTaskMem((int)MaxBuffer * sizeof(char));
uint byteReturned = GetPrivateProfileSectionNames(pReturnedString, MaxBuffer, filePath);
if (byteReturned != 0)
{
// 读取指定内存内容
string local = Marshal.PtrToStringAuto(pReturnedString, (int)byteReturned).ToString();
// 每个节点之间用\0分隔,末尾有一个\0
sections = local.Split(new char[] { '\0' }, StringSplitOptions.RemoveEmptyEntries);
}
return sections;
}
// 显示所有分区
private void PortNameComboBox_MouseClick(object sender, MouseEventArgs e)
{
string[] sections = ReadIniAllSectionName(Directory.GetCurrentDirectory() + "\\Column.ini");
for (int item = 0; item < sections.Length; item++)
{
configureLabel.Items.Add(sections[item]); // 显示到列表
}
}
效果如图
五、适用于不同放大倍数的截屏
//声亮一个API函数
[System.Runtime.InteropServices.DllImportAttribute("gdi32.dll")]
private static extern bool BitBlt(
IntPtr hdcDest, // 目的 DC的句柄
int nXDest,
int nYDest,
int nWidth,
int nHeight,
IntPtr hdcSrc, // 源DC的句柄
int nXSrc,
int nYSrc,
System.Int32 dwRop // 光栅的处置数值
);
private void butpicture_Click(object sender, EventArgs e)
{
//创立一个以以后屏幕为模板的图象
Graphics g1 = this.CreateGraphics();
//创立以屏幕大小为尺度的位图
Image MyImage = new Bitmap(this.Width, this.Height, g1);
Graphics g2 = Graphics.FromImage(MyImage);
//得到屏幕的DC
IntPtr dc1 = g1.GetHdc();
//得到Bitmap的DC
IntPtr dc2 = g2.GetHdc();
//调用彼API函数,完成屏幕捕捉
BitBlt(dc2, 0, 0, this.Width, this.Height, dc1, 0, 0, 13369376);
//开释掉屏幕的DC
g1.ReleaseHdc(dc1);
//开释掉Bitmap的DC
g2.ReleaseHdc(dc2);
// 获取系统桌面路径
string path = Environment.GetFolderPath(Environment.SpecialFolder.Desktop);
char asicc1 = (char)92;
// 在桌面保存文件
MyImage.Save(@"" + path + "" + asicc1 + "" + ".png")
MyImage.Dispose();
// 仅适用于截图100%缩放比例截图
/* Bitmap bit = new Bitmap(this.Width, this.Height);
Graphics g = Graphics.FromImage(bit);
g.CompositingQuality = System.Drawing.Drawing2D.CompositingQuality.HighQuality;
g.CopyFromScreen(this.Left, this.Top, 0, 0, new Size(this.Width, this.Height));
bit.Save(@"d:\00USER\Desktop\" + textBox1.Text + "-" + tbox_VersionNum.Text.Replace("v", "V") + "-" + DateTime.Now.ToString("yyMMdd") + ".png");
bit.Dispose();*/
}
六、数据处理
public partial class verifier : Form
{
private Queue<char> bufferQueue = null;
}
private void verifier_Load(object sender, EventArgs e)
{
// 实例化
bufferQueue = new Queue<char>();
}
private void framesDispose(string dataTemp)
{
// 解析数据
foreach (char item in dataTemp)
{
// 入列
bufferQueue.Enqueue(item);
}
// 数据处理
decodeData(bufferQueue);
}
public void decodeData(Queue<char> bufferQueue)
{
int bufferLenth = bufferQueue.Count;
if (textBox1.Text.Contains("rise"))
{
int riselenth = 0;
for (int i = 0; i < bufferLenth; i++)
{
if (bufferQueue.ToArray()[i] == 'r' && bufferQueue.ToArray()[i + 1] == 'i')
{
int rieshead = i + 4;
int risefinish = 0;
for (int parameter = rieshead; parameter < bufferLenth; parameter++)
{
if (bufferQueue.ToArray()[parameter] == '-')
{
risefinish = parameter;
riselenth = risefinish - rieshead;
char[] distance = new char[riselenth];
Array.Copy(bufferQueue.ToArray(), rieshead, distance, 0, riselenth); // 将数据复制到另外的数组中
ResetDistanceTextBox.Text = new string(distance);
specialL = true;
break;
}
}
}
}
}
//出列
for (int m = 0; m < bufferLenth; m++)
{
bufferQueue.Dequeue();
}
}
七、委托线程
出现多线程冲突时,引用委托函数处理冲突部分程序。
using System.Runtime.InteropServices;
namespace XX // XX指项目名称
{
[Serializable]
[ComVisible(true)]
public delegate void EventHandler(object sender, EventArgs e);
}
// 委托函数
this.Invoke(new Action(() =>
{
disconnect(); //委托函数处理内容
}));
八、文本框的处理
1.显示文本框滚动条
2、文本内容显示垂直居中
private void Form1_Load(object sender, EventArgs e)
{
SetStaticText("推拽文件区域");
}
public void SetStaticText(string text)
{
//加入换行
for (int i = 0; i < 3; i++)
{
text = Environment.NewLine + text;
}
textBox2.Text = text;
}
显示效果
3、取消焦点时文本选中
现象:打开时,文本框为焦点,内容被全选
public void SetStaticText(string text)
{
//加入换行
for (int i = 0; i < 3; i++)
{
text = Environment.NewLine + text;
}
textBox2.Text = text;
textBox2.Select(0, 0); //选中文本最前面
}
效果展示
4、取消文本框光标
// 不显示光标文件导入
[DllImport("user32", EntryPoint = "HideCaret")]
private static extern bool HideCaret(IntPtr hWnd);
private void Form1_Load(object sender, EventArgs e)
{
SetStaticText("推拽文件区域");
textBox2.GotFocus += textBox2_GotFocus; // 添加事件
}
void textBox2_GotFocus(object sender, EventArgs e)
{
HideCaret((sender as TextBox).Handle); // 取消文本光标显示
}
显示效果
九、常用语句
语句 | 含义 |
---|---|
A.Split(‘-’); | 字符串根据“-”进行分割 |
A.Contains(“B”) | 字符串A语句中包含B |
Convert.ToInt32(A) | 将字符串A强制转换成int型 |
DateTime.Now.ToString(“yyMMdd”) | 显示时间,例如220120 |
A = new string(B) | 强制将B转换成字符串赋值给A |
MessageBox.Show(“请检查命名”, “提示”); | 弹窗显示 |
A_CheckedChanged(A, new EventArgs()); | 调用窗口A的事件 |
Console.WriteLine(A); | 将A显示在调试框中 |
Thread.Sleep(A); | 延时Ams |
B= A.Substring(0, 1); | 获取字符串A从0-1的字符,赋给B |
int.TryParse(A, out B); | 把A转成int型,再赋值给B,并进行转换校验 |
string B = A.Replace(“)”, “”); | 将字符串A中的“("删除,并赋值B |
注:使用串口的程序在关闭串口后要引用窗口关闭函数(FormClosed),释放串口。