【问题标题】:How do I get process name of an open port in C#?如何在 C# 中获取打开端口的进程名称?
【发布时间】:2010-12-13 02:28:21
【问题描述】:

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

【问题讨论】:

    标签: c# port


    【解决方案1】:

    您可以执行netstat -anb 并处理输出。

    【讨论】:

    • 任何其他想法...通过 .net 或 win32 apis
    【解决方案2】:

    【讨论】:

      【解决方案3】:

      经过一番搜索,我将Cheyne Wallace's solution 改编成一个静态类,该类具有一个属性,该属性使用NetStat 以列表的形式返回进程到端口的映射。

      课程如下:

      using System;
      using System.Collections.Generic;
      using System.Diagnostics;
      using System.IO;
      using System.Text.RegularExpressions;
      
      namespace MyNamespace
      {
          /// <summary>
          /// Static class that returns the list of processes and the ports those processes use.
          /// </summary>
          public static class ProcessPorts
          {
              /// <summary>
              /// A list of ProcesesPorts that contain the mapping of processes and the ports that the process uses.
              /// </summary>
              public static List<ProcessPort> ProcessPortMap
              {
                  get
                  {
                      return GetNetStatPorts();
                  }
              }
      
      
              /// <summary>
              /// 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.
              /// </summary>
              /// <returns></returns>
              private static List<ProcessPort> GetNetStatPorts()
              {
                  List<ProcessPort> ProcessPorts = new List<ProcessPort>();
      
                  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;
              }
      
              /// <summary>
              /// Private method that handles pulling the process name (if one exists) from the process id.
              /// </summary>
              /// <param name="ProcessId"></param>
              /// <returns></returns>
              private static string GetProcessName(int ProcessId)
              {
                  string procName = "UNKNOWN";
      
                  try
                  {
                      procName = Process.GetProcessById(ProcessId).ProcessName;
                  }
                  catch { }
      
                  return procName;
              }
          }
      
          /// <summary>
          /// A mapping for processes to ports and ports to processes that are being used in the system.
          /// </summary>
          public class ProcessPort
          {
              private string _ProcessName = String.Empty;
              private int _ProcessId = 0;
              private string _Protocol = String.Empty;
              private int _PortNumber = 0;
      
              /// <summary>
              /// Internal constructor to initialize the mapping of process to port.
              /// </summary>
              /// <param name="ProcessName">Name of process to be </param>
              /// <param name="ProcessId"></param>
              /// <param name="Protocol"></param>
              /// <param name="PortNumber"></param>
              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();
              }
          }
      }
      

      【讨论】:

      • 进程 ID 是 Int32,而不是 Int16 :)
      • 嗨,格雷格和科迪,我的机器收到以下错误代码。我找到了另一个解决方案。所以我也在这里发布了那个版本。错误消息:无法将以下 NetStat 行转换为进程到端口的映射。 TCP 0.0.0.0:8222 0.0.0.0:0 LISTENING 63700 无法将以下 NetStat 行转换为进程到端口的映射。 TCP 0.0.0.0:43525 0.0.0.0:0 LISTENING 63700 无法将以下 NetStat 行转换为进程到端口的映射。 TCP 0.0.0.0:46462 0.0.0.0:0 监听 63700
      【解决方案4】:

      不确定为什么 Greg Grater 的版本无法解析我机器中的 netstat 输出。 相反,我发现 Madhusudana 在他的博客文章中的 TcpHelperUtil 课程对我有用。

      https://bsmadhu.wordpress.com/2012/09/11/identifying-process-using-tcp-port-in-net/

      简单用法:

      var details = new TcpHelperUtil().GetPortDetails(port);
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2015-10-14
        相关资源
        最近更新 更多