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