開發一款 C# 工具,輸入目標主機,顯示路由追蹤路徑(同系統 tracert/traceroute)。
using System.Diagnostics;
public string TraceRoute(string host)
{
var psi = new ProcessStartInfo
{
FileName = "cmd.exe",
Arguments = $"/c tracert {host}", // /c 執行命令後退出
UseShellExecute = false, // 必須 false 才能重定向
RedirectStandardOutput = true, // 捕獲標準輸出
RedirectStandardError = true, // 捕獲錯誤輸出
CreateNoWindow = true, // 無控制台窗口
StandardOutputEncoding = Encoding.GetEncoding("GBK"), // 中文系統編碼
StandardErrorEncoding = Encoding.GetEncoding("GBK")
};
using (var proc = Process.Start(psi))
{
if (proc == null) return "啟動失敗";
string output = proc.StandardOutput.ReadToEnd();
string error = proc.StandardError.ReadToEnd();
proc.WaitForExit(30000); // 30秒超時
return string.IsNullOrEmpty(error) ? output : $"錯誤: {error}";
}
}
| 屬性 | 作用 |
|---|---|
UseShellExecute=false | 啟用重定向,否則 RedirectStandardOutput 無效 |
Arguments="/c tracert ..." | /c 執行完畢關閉 cmd,避免進程殭屍 |
StandardOutputEncoding | 解決中文系統下 tracert 輸出亂碼(GBK/CP936) |
WaitForExit(timeout) | 防止網絡異常導致進程無限等待 |
若需跨平台或更精細控制,可使用 System.Net.NetworkInformation.Ping + TTL 遞增實現:
public IEnumerable TraceRoutePure(string host, int maxHops = 30)
{
var ip = Dns.GetHostAddresses(host)[0];
byte[] buffer = new byte[32];
for (int ttl = 1; ttl <= maxHops; ttl++)
{
using (var ping = new Ping())
{
var options = new PingOptions(ttl, true); // DontFragment=true
var reply = ping.Send(ip, 3000, buffer, options);
yield return $"{ttl}\t{reply.Address}\t{reply.RoundtripTime}ms\t{reply.Status}";
if (reply.Status == IPStatus.Success) yield break;
}
}
}
根據場景選型:桌面小工具用 Process 最快;服務端監控組件建議純 C# 實現。