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

Posted

技术标签:

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

【问题讨论】:

【参考方案1】:

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

【讨论】:

任何其他想法...通过 .net 或 win32 apis【参考方案2】:

http://www.codeproject.com/KB/IP/iphlpapi.aspx 也可能有帮助

【讨论】:

【参考方案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("0v6", Tokens[1]) : String.Format("0v4", 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);

【讨论】:

以上是关于如何在 C# 中获取打开端口的进程名称?的主要内容,如果未能解决你的问题,请参考以下文章

C#如何通过进程名称获取指定窗口的句柄,通过该句柄获取该窗口的标题?

如何在 Linux/Unix 系统中验证端口是不是打开

如何在 Linux 中查找进程 ID 打开的端口?

如何在 C# 中按进程获取打开文件句柄的列表?

c#如何实现串口通信读取数据

如何使用 c# 以编程方式在 domino 服务器中获取 CA 配置的验证者名称列表?