首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> .NET 網頁程式設計 >> C# >> 關於C#

C# 呼叫外部 Ping 指令並解析結果監控網路連線狀態

     編輯:關於C#

核心原理

利用 System.Diagnostics.Process 啟動 cmd.exe,透過標準輸入寫入 ping 指令,再從標準輸出讀取結果字串進行分析。適用於需相容舊系統、無法使用 System.Net.NetworkInformation.Ping 類別的場景。

完整實作類別


using System;
using System.Diagnostics;

public static class NetworkHelper
{
    /// 
    /// 執行 Ping 並回傳連線狀態描述
    /// 
    /// 目標 IP 或主機名
    /// 單次等待逾時毫秒數
    /// 連線狀態文字
    public static string PingHost(string ipAddress, int timeoutMs = 3000)
    {
        var psi = new ProcessStartInfo
        {
            FileName = "cmd.exe",
            UseShellExecute = false,           // 必須 false 才能重導向
            RedirectStandardInput = true,
            RedirectStandardOutput = true,
            RedirectStandardError = true,
            CreateNoWindow = true,             // 不顯示黑色視窗
            StandardOutputEncoding = System.Text.Encoding.GetEncoding(950), // 繁體中文系統預設代碼頁
            StandardErrorEncoding = System.Text.Encoding.GetEncoding(950)
        };

        using (var process = Process.Start(psi))
        {
            if (process == null) return "無法啟動進程";

            // 寫入指令:-n 1 只送一個封包,-w 設定逾時(毫秒)
            string cmd = $"ping -n 1 -w {timeoutMs} {ipAddress}";
            process.StandardInput.WriteLine(cmd);
            process.StandardInput.WriteLine("exit"); // 結束 cmd

            string output = process.StandardOutput.ReadToEnd();
            process.WaitForExit(5000); // 總等待上限

            return AnalyzePingOutput(output);
        }
    }

    private static string AnalyzePingOutput(string output)
    {
        if (string.IsNullOrEmpty(output)) return "無回應內容";

        // 關鍵字判斷 (不同語系 Windows 輸出不同,建議用正則或多語系關鍵字)
        if (output.Contains("(0% loss)") || output.Contains("(0% 遺失)") || output.Contains("TTL="))
            return "連線正常";
        if (output.Contains("Destination host unreachable") || output.Contains("找不到主機"))
            return "無法到達目的主機";
        if (output.Contains("Request timed out") || output.Contains("逾時"))
            return "連線逾時";
        if (output.Contains("Unknown host") || output.Contains("無法解析主機"))
            return "無法解析主機名稱";

        return "未知狀態:" + output.Substring(0, Math.Min(200, output.Length));
    }
}

使用範例


private async void btnCheckNetwork_Click(object sender, EventArgs e)
{
    btnCheckNetwork.Enabled = false;
    lblStatus.Text = "檢測中...";

    // 非同步執行避免凍結 UI
    string result = await Task.Run(() => NetworkHelper.PingHost("8.8.8.8"));

    lblStatus.Text = result;
    btnCheckNetwork.Enabled = true;
}

進階:使用 .NET 內建 Ping 類別 (推薦現代專案)


using System.Net.NetworkInformation;

public static string PingWithDotNet(string host)
{
    try
    {
        using (var ping = new Ping())
        {
            var reply = ping.Send(host, 3000); // 3 秒逾時
            return reply.Status == IPStatus.Success 
                ? $"連線正常 (RTT: {reply.RoundtripTime}ms)" 
                : $"失敗:{reply.Status}";
        }
    }
    catch (Exception ex)
    {
        return $"例外:{ex.Message}";
    }
}

兩種方案比較

維度Process 呼叫 ping.exeSystem.Net.NetworkInformation.Ping
相容性極高 (任何有 ping 指令的 OS).NET Framework / .NET Core 完整支援
效能啟動進程開銷大 (~10-50ms)直接呼叫 ICMP API,極快
權限需求一般使用者即可需 Raw Socket 權限 (Linux 需 root/Capability)
輸出解析需處理多語系文字、格式差異結構化物件,型別安全
支援非同步需自行 Task.Run 包裝內建 SendPingAsync

適用場景建議

  • 新專案 / .NET Core / 跨平台:優先使用 Ping 類別。
  • 舊版 .NET Framework 專案、受限環境、需完全模擬使用者執行指令:使用 Process 方案。
  • 需支援 IPv6、自訂封包大小、記錄路由:Ping 類別功能更豐富。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved