如何在C#中获取开放端口的进程名称?

如何在C#中获取开放端口的进程名称?

经过一番搜索后,我将Cheyne Wallace的解决方案改编为静态类,其中一个属性使用NetStat以列表的forms返回进程到端口的映射。

这是class级:

using System; using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Text.RegularExpressions; namespace MyNamespace { ///  /// Static class that returns the list of processes and the ports those processes use. ///  public static class ProcessPorts { ///  /// A list of ProcesesPorts that contain the mapping of processes and the ports that the process uses. ///  public static List ProcessPortMap { get { return GetNetStatPorts(); } } ///  /// This method distills the output from netstat -a -n -o into a list of ProcessPorts that provide a mapping between /// the process (name and id) and the ports that the process is using. ///  ///  private static List GetNetStatPorts() { List ProcessPorts = new List(); try { using (Process Proc = new Process()) { ProcessStartInfo StartInfo = new ProcessStartInfo(); StartInfo.FileName = "netstat.exe"; StartInfo.Arguments = "-a -n -o"; StartInfo.WindowStyle = ProcessWindowStyle.Hidden; StartInfo.UseShellExecute = false; StartInfo.RedirectStandardInput = true; StartInfo.RedirectStandardOutput = true; StartInfo.RedirectStandardError = true; Proc.StartInfo = StartInfo; Proc.Start(); StreamReader StandardOutput = Proc.StandardOutput; StreamReader StandardError = Proc.StandardError; string NetStatContent = StandardOutput.ReadToEnd() + StandardError.ReadToEnd(); string NetStatExitStatus = Proc.ExitCode.ToString(); if (NetStatExitStatus != "0") { Console.WriteLine("NetStat command failed. This may require elevated permissions."); } string[] NetStatRows = Regex.Split(NetStatContent, "\r\n"); foreach (string NetStatRow in NetStatRows) { string[] Tokens = Regex.Split(NetStatRow, "\\s+"); if (Tokens.Length > 4 && (Tokens[1].Equals("UDP") || Tokens[1].Equals("TCP"))) { string IpAddress = Regex.Replace(Tokens[2], @"\[(.*?)\]", "1.1.1.1"); try { ProcessPorts.Add(new ProcessPort( Tokens[1] == "UDP" ? GetProcessName(Convert.ToInt16(Tokens[4])) : GetProcessName(Convert.ToInt16(Tokens[5])), Tokens[1] == "UDP" ? Convert.ToInt16(Tokens[4]) : Convert.ToInt16(Tokens[5]), IpAddress.Contains("1.1.1.1") ? String.Format("{0}v6", Tokens[1]) : String.Format("{0}v4", Tokens[1]), Convert.ToInt32(IpAddress.Split(':')[1]) )); } catch { Console.WriteLine("Could not convert the following NetStat row to a Process to Port mapping."); Console.WriteLine(NetStatRow); } } else { if (!NetStatRow.Trim().StartsWith("Proto") && !NetStatRow.Trim().StartsWith("Active") && !String.IsNullOrWhiteSpace(NetStatRow)) { Console.WriteLine("Unrecognized NetStat row to a Process to Port mapping."); Console.WriteLine(NetStatRow); } } } } } catch (Exception ex) { Console.WriteLine(ex.Message); } return ProcessPorts; } ///  /// Private method that handles pulling the process name (if one exists) from the process id. ///  ///  ///  private static string GetProcessName(int ProcessId) { string procName = "UNKNOWN"; try { procName = Process.GetProcessById(ProcessId).ProcessName; } catch { } return procName; } } ///  /// A mapping for processes to ports and ports to processes that are being used in the system. ///  public class ProcessPort { private string _ProcessName = String.Empty; private int _ProcessId = 0; private string _Protocol = String.Empty; private int _PortNumber = 0; ///  /// Internal constructor to initialize the mapping of process to port. ///  /// Name of process to be  ///  ///  ///  internal ProcessPort (string ProcessName, int ProcessId, string Protocol, int PortNumber) { _ProcessName = ProcessName; _ProcessId = ProcessId; _Protocol = Protocol; _PortNumber = PortNumber; } public string ProcessPortDescription { get { return String.Format("{0} ({1} port {2} pid {3})", _ProcessName, _Protocol, _PortNumber, _ProcessId); } } public string ProcessName { get { return _ProcessName; } } public int ProcessId { get { return _ProcessId; } } public string Protocol { get { return _Protocol; } } public int PortNumber { get { return _PortNumber; } } } } 

从简单的控制台应用程序调用可能如下所示:

 using System; namespace MyNamespace { class Program { static void Main(string[] args) { foreach (ProcessPort p in ProcessPorts.ProcessPortMap.FindAll(x => x.ProcessName.ToLower() == "myprocess")) //extension is not needed. { Console.WriteLine(p.ProcessPortDescription); } foreach (ProcessPort p in ProcessPorts.ProcessPortMap.FindAll(x => x.PortNumber == 4444)) { Console.WriteLine(p.ProcessPortDescription); } Console.WriteLine("Press any key to continue..."); Console.ReadLine(); } } } 

您可以执行netstat -anb和进程输出。

不久前我也有同样的问题。 单独使用.net并不是一种简单的方法。 您检索端口号和进程ID,但不检索两者之间的关系。

这段代码使用NetStat来解决它。

在C#中获取活动端口和关联进程名称

http://www.cheynewallace.com/get-active-ports-and-associated-process-names-in-c/