Recently I found myself needing to find a way to determine what open and listening ports along with their associated running processes are currently active on a Windows machine using C#.
Some extensive Googling returned pretty dismal results.
Retrieving a list of open ports is simple.
Retrieving a list of running processes is simple.
A combination of the two is not.
There were a few external libraries, but it just seemed like overkill for something that should be a pretty simple task.
The solution was to just parse the output of a netstat -a -n -o command. The result from this code snip will return a list of “Port” objects which contain process names, port number and protocol as properties.
05 | public static List<Port> GetNetStatPorts() |
07 | var Ports = new List<Port>(); |
10 | using (Process p = new Process()) { |
12 | ProcessStartInfo ps = new ProcessStartInfo(); |
13 | ps.Arguments = "-a -n -o" ; |
14 | ps.FileName = "netstat.exe" ; |
15 | ps.UseShellExecute = false ; |
16 | ps.WindowStyle = ProcessWindowStyle.Hidden; |
17 | ps.RedirectStandardInput = true ; |
18 | ps.RedirectStandardOutput = true ; |
19 | ps.RedirectStandardError = true ; |
24 | StreamReader stdOutput = p.StandardOutput; |
25 | StreamReader stdError = p.StandardError; |
27 | string content = stdOutput.ReadToEnd() + stdError.ReadToEnd(); |
28 | string exitStatus = p.ExitCode.ToString(); |
30 | if (exitStatus != "0" ) { |
35 | string [] rows = Regex.Split(content, "\r\n" ); |
36 | foreach ( string row in rows) { |
38 | string [] tokens = Regex.Split(row, "\\s+" ); |
39 | if (tokens.Length > 4 && (tokens[1].Equals( "UDP" ) || tokens[1].Equals( "TCP" ))) { |
40 | string localAddress = Regex.Replace(tokens[2], @"\[(.*?)\]" , "1.1.1.1" ); |
42 | protocol = localAddress.Contains( "1.1.1.1" ) ? String.Format( "{0}v6" ,tokens[1]) : String.Format( "{0}v4" ,tokens[1]), |
43 | port_number = localAddress.Split( ':' )[1], |
44 | process_name = tokens[1] == "UDP" ? LookupProcess(Convert.ToInt16(tokens[4])) : LookupProcess(Convert.ToInt16(tokens[5])) |
52 | Console.WriteLine(ex.Message) |
57 | public static string LookupProcess( int pid) |
60 | try { procName = Process.GetProcessById(pid).ProcessName; } |
61 | catch (Exception) { procName = "-" ;} |
74 | return string .Format( "{0} ({1} port {2})" , this .process_name, this .protocol, this .port_number); |
78 | public string port_number { get ; set ; } |
79 | public string process_name { get ; set ; } |
80 | public string protocol { get ; set ; } |