How do I get process name of an open port in C#?

后端 未结 3 1470
日久生厌
日久生厌 2021-02-13 03:40

How do I get process name of an open port in C#?

3条回答
  •  伪装坚强ぢ
    2021-02-13 04:20

    After some searching, I've adapted Cheyne Wallace's solution into a static class with one property that returns a mapping of Processes to Ports in the form of a list using NetStat.

    Here's the 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; }
            }
        }
    }
    

    Calling from a simple console application may look like:

    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();
            }
        }
    }
    

提交回复
热议问题