1. 基础版本 - 检查串口状态

using System;
using System.IO.Ports;
using System.Threading;

public class SerialPortChecker
{
    /// <summary>
    /// 检查串口是否可以正常打开和关闭
    /// </summary>
    /// <param name="portName">串口名称,如 "COM4"</param>
    /// <param name="baudRate">波特率,默认9600</param>
    /// <returns>检查结果对象</returns>
    public static SerialPortCheckResult CheckSerialPort(string portName, int baudRate = 9600)
    {
        var result = new SerialPortCheckResult
        {
            PortName = portName,
            BaudRate = baudRate
        };

        try
        {
            // 检查串口是否存在
            if (!IsSerialPortExists(portName))
            {
                result.IsSuccess = false;
                result.ErrorMessage = $"串口 {portName} 不存在";
                return result;
            }

            result.PortExists = true;

            // 尝试打开和关闭串口
            using (SerialPort serialPort = new SerialPort(portName, baudRate))
            {
                try
                {
                    // 尝试打开串口
                    serialPort.Open();
                    result.CanOpen = true;
                    result.OpenTime = DateTime.Now;

                    // 短暂延迟,确保端口稳定
                    Thread.Sleep(100);

                    // 尝试关闭串口
                    serialPort.Close();
                    result.CanClose = true;
                    result.CloseTime = DateTime.Now;

                    result.IsSuccess = true;
                    result.Message = "串口可以正常打开和关闭";
                }
                catch (UnauthorizedAccessException ex)
                {
                    result.IsSuccess = false;
                    result.ErrorMessage = $"串口被其他应用程序占用: {ex.Message}";
                }
                catch (Exception ex)
                {
                    result.IsSuccess = false;
                    result.ErrorMessage = $"串口操作失败: {ex.Message}";
                }
            }
        }
        catch (Exception ex)
        {
            result.IsSuccess = false;
            result.ErrorMessage = $"检查串口时发生异常: {ex.Message}";
        }

        return result;
    }

    /// <summary>
    /// 检查串口是否存在
    /// </summary>
    public static bool IsSerialPortExists(string portName)
    {
        string[] ports = SerialPort.GetPortNames();
        foreach (string port in ports)
        {
            if (port.Equals(portName, StringComparison.OrdinalIgnoreCase))
                return true;
        }
        return false;
    }

    /// <summary>
    /// 获取所有可用的串口列表
    /// </summary>
    public static string[] GetAvailablePorts()
    {
        return SerialPort.GetPortNames();
    }
}

public class SerialPortCheckResult
{
    public string PortName { get; set; }
    public int BaudRate { get; set; }
    public bool IsSuccess { get; set; }
    public bool PortExists { get; set; }
    public bool CanOpen { get; set; }
    public bool CanClose { get; set; }
    public DateTime? OpenTime { get; set; }
    public DateTime? CloseTime { get; set; }
    public string Message { get; set; }
    public string ErrorMessage { get; set; }

    public override string ToString()
    {
        if (IsSuccess)
            return $"✓ 串口 {PortName} 检查正常: {Message}";
        else
            return $"✗ 串口 {PortName} 检查失败: {ErrorMessage}";
    }
}

2. 增强版本 - 支持更多参数和异步操作

using System;
using System.IO.Ports;
using System.Threading;
using System.Threading.Tasks;

public class AdvancedSerialPortChecker
{
    /// <summary>
    /// 异步检查串口状态
    /// </summary>
    public static async Task<SerialPortCheckResult> CheckSerialPortAsync(
        string portName, 
        int baudRate = 9600,
        Parity parity = Parity.None,
        int dataBits = 8,
        StopBits stopBits = StopBits.One,
        int timeout = 2000)
    {
        return await Task.Run(() => CheckSerialPortWithDetails(portName, baudRate, parity, dataBits, stopBits, timeout));
    }

    /// <summary>
    /// 详细检查串口状态
    /// </summary>
    public static SerialPortCheckResult CheckSerialPortWithDetails(
        string portName,
        int baudRate = 9600,
        Parity parity = Parity.None,
        int dataBits = 8,
        StopBits stopBits = StopBits.One,
        int timeout = 2000)
    {
        var result = new SerialPortCheckResult
        {
            PortName = portName,
            BaudRate = baudRate,
            Parity = parity,
            DataBits = dataBits,
            StopBits = stopBits
        };

        try
        {
            // 检查串口是否存在
            if (!SerialPortChecker.IsSerialPortExists(portName))
            {
                result.IsSuccess = false;
                result.ErrorMessage = $"串口 {portName} 不存在";
                return result;
            }

            result.PortExists = true;

            using (SerialPort serialPort = new SerialPort(portName, baudRate, parity, dataBits, stopBits))
            {
                serialPort.ReadTimeout = timeout;
                serialPort.WriteTimeout = timeout;

                try
                {
                    // 记录开始时间
                    DateTime startTime = DateTime.Now;

                    // 尝试打开串口
                    serialPort.Open();
                    result.CanOpen = true;
                    result.OpenTime = DateTime.Now;

                    // 保持打开状态一小段时间,模拟实际使用
                    Thread.Sleep(500);

                    // 尝试关闭串口
                    serialPort.Close();
                    result.CanClose = true;
                    result.CloseTime = DateTime.Now;

                    result.Duration = (result.CloseTime - result.OpenTime).Value.TotalMilliseconds;
                    result.IsSuccess = true;
                    result.Message = $"串口配置正常 (波特率:{baudRate}, 数据位:{dataBits}, 停止位:{stopBits}, 校验位:{parity})";
                }
                catch (TimeoutException)
                {
                    result.IsSuccess = false;
                    result.ErrorMessage = "串口操作超时,可能被占用或配置错误";
                }
                catch (UnauthorizedAccessException)
                {
                    result.IsSuccess = false;
                    result.ErrorMessage = "串口被其他应用程序占用或无访问权限";
                }
                catch (Exception ex)
                {
                    result.IsSuccess = false;
                    result.ErrorMessage = $"串口操作异常: {ex.Message}";
                }
            }
        }
        catch (Exception ex)
        {
            result.IsSuccess = false;
            result.ErrorMessage = $"检查串口时发生系统异常: {ex.Message}";
        }

        return result;
    }
}

// 扩展的检查结果类
public class DetailedSerialPortCheckResult : SerialPortCheckResult
{
    public Parity Parity { get; set; }
    public int DataBits { get; set; }
    public StopBits StopBits { get; set; }
    public double Duration { get; set; } // 操作持续时间(毫秒)

    public override string ToString()
    {
        if (IsSuccess)
        {
            return $"✓ 串口 {PortName} 检查正常 | 波特率:{BaudRate} | 数据位:{DataBits} | 停止位:{StopBits} | 校验位:{Parity} | 耗时:{Duration}ms";
        }
        else
        {
            return $"✗ 串口 {PortName} 检查失败: {ErrorMessage}";
        }
    }
}

3. 批量检查多个串口

using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;

public class BatchSerialPortChecker
{
    /// <summary>
    /// 批量检查多个串口
    /// </summary>
    public static async Task<List<SerialPortCheckResult>> CheckMultiplePortsAsync(
        List<string> portNames, 
        int baudRate = 9600)
    {
        var tasks = portNames.Select(portName => 
            AdvancedSerialPortChecker.CheckSerialPortAsync(portName, baudRate));
        
        var results = await Task.WhenAll(tasks);
        return results.ToList();
    }

    /// <summary>
    /// 检查所有可用的串口
    /// </summary>
    public static async Task<List<SerialPortCheckResult>> CheckAllAvailablePortsAsync(int baudRate = 9600)
    {
        string[] availablePorts = SerialPortChecker.GetAvailablePorts();
        return await CheckMultiplePortsAsync(availablePorts.ToList(), baudRate);
    }
}

4. 使用示例

class Program
{
    static async Task Main(string[] args)
    {
        string portName = "COM4";

        Console.WriteLine("串口状态检查工具");
        Console.WriteLine("=================");

        // 方法1: 基础检查
        Console.WriteLine($"\n1. 基础检查 {portName}:");
        var basicResult = SerialPortChecker.CheckSerialPort(portName);
        Console.WriteLine(basicResult.ToString());

        // 方法2: 详细检查
        Console.WriteLine($"\n2. 详细检查 {portName}:");
        var detailedResult = AdvancedSerialPortChecker.CheckSerialPortWithDetails(
            portName, 
            baudRate: 115200, 
            parity: Parity.None, 
            dataBits: 8, 
            stopBits: StopBits.One);
        Console.WriteLine(detailedResult.ToString());

        // 方法3: 异步检查
        Console.WriteLine($"\n3. 异步检查 {portName}:");
        var asyncResult = await AdvancedSerialPortChecker.CheckSerialPortAsync(portName);
        Console.WriteLine(asyncResult.ToString());

        // 方法4: 检查所有可用串口
        Console.WriteLine($"\n4. 检查所有可用串口:");
        var allPortsResult = await BatchSerialPortChecker.CheckAllAvailablePortsAsync();
        foreach (var result in allPortsResult)
        {
            Console.WriteLine($"   {result}");
        }

        // 方法5: 检查串口是否存在
        Console.WriteLine($"\n5. 串口存在性检查:");
        string[] availablePorts = SerialPortChecker.GetAvailablePorts();
        Console.WriteLine($"   可用串口: {string.Join(", ", availablePorts)}");
        Console.WriteLine($"   {portName} 是否存在: {SerialPortChecker.IsSerialPortExists(portName)}");
    }
}

5. 控制台应用程序完整示例

using System;
using System.Threading.Tasks;

class SerialPortTester
{
    static async Task Main(string[] args)
    {
        while (true)
        {
            Console.Clear();
            Console.WriteLine("=== 串口连通性测试工具 ===");
            Console.WriteLine("1. 检查特定串口");
            Console.WriteLine("2. 检查所有串口");
            Console.WriteLine("3. 退出");
            Console.Write("请选择操作: ");

            string choice = Console.ReadLine();

            switch (choice)
            {
                case "1":
                    await CheckSpecificPort();
                    break;
                case "2":
                    await CheckAllPorts();
                    break;
                case "3":
                    return;
                default:
                    Console.WriteLine("无效选择,按任意键继续...");
                    Console.ReadKey();
                    break;
            }
        }
    }

    static async Task CheckSpecificPort()
    {
        Console.Write("请输入串口名称 (如 COM4): ");
        string portName = Console.ReadLine().ToUpper();

        if (string.IsNullOrWhiteSpace(portName))
        {
            Console.WriteLine("串口名称不能为空!");
            return;
        }

        Console.WriteLine($"正在检查串口 {portName}...");

        var result = await AdvancedSerialPortChecker.CheckSerialPortAsync(portName);

        // 显示彩色结果
        Console.ForegroundColor = result.IsSuccess ? ConsoleColor.Green : ConsoleColor.Red;
        Console.WriteLine($"\n检查结果: {result}");
        Console.ResetColor();

        if (result.IsSuccess)
        {
            Console.WriteLine($"   打开时间: {result.OpenTime}");
            Console.WriteLine($"   关闭时间: {result.CloseTime}");
        }

        Console.WriteLine("\n按任意键继续...");
        Console.ReadKey();
    }

    static async Task CheckAllPorts()
    {
        Console.WriteLine("正在扫描所有可用串口...");

        var results = await BatchSerialPortChecker.CheckAllAvailablePortsAsync();

        Console.WriteLine($"\n找到 {results.Count} 个串口:");
        Console.WriteLine("======================");

        foreach (var result in results)
        {
            Console.ForegroundColor = result.IsSuccess ? ConsoleColor.Green : ConsoleColor.Red;
            Console.WriteLine($"  {result.PortName

Logo

Agent 垂直技术社区,欢迎活跃、内容共建。

更多推荐