Improved version of @yohannist's answer (missing using
, unnecessary GUI window and some other things). The following code can be used as:
ProcMgr.KillWherePort(port)
Implementation:
public class DataOrException<T>
{
public T? Data { get; set; }
public Exception? Exception { get; set; }
public DataOrException(T? data)
{
Data = data;
}
public DataOrException(Exception? exception)
{
Exception = exception;
}
}
public enum ProcKillResult
{
Ok,
PortEmpty
}
public class PRC
{
public int PID { get; set; }
public int Port { get; set; }
public string Protocol { get; set; }
}
public static class ProcMgr
{
public static DataOrException<ProcKillResult> KillWherePort(int port)
{
DataOrException<List<PRC>> processes = GetAllProcesses();
if (processes.Data is null || processes.Exception is not null)
{
return new DataOrException<ProcKillResult>(processes.Exception);
}
PRC? offendingProcess = processes.Data.FirstOrDefault(x => x.Port == port);
if (offendingProcess is not null)
{
try
{
Process.GetProcessById(offendingProcess.PID).Kill();
return new DataOrException<ProcKillResult>(ProcKillResult.Ok);
}
catch (Exception ex)
{
return new DataOrException<ProcKillResult>(ex);
}
}
return new DataOrException<ProcKillResult>(ProcKillResult.PortEmpty);
}
private static readonly Regex newlineRegex = new Regex(Environment.NewLine, RegexOptions.Compiled);
public static DataOrException<List<PRC>> GetAllProcesses()
{
ProcessStartInfo pStartInfo = new ProcessStartInfo
{
FileName = "netstat.exe",
Arguments = "-a -n -o",
CreateNoWindow = true,
UseShellExecute = false,
RedirectStandardInput = true,
RedirectStandardOutput = true,
RedirectStandardError = true
};
using Process process = new Process();
process.StartInfo = pStartInfo;
process.Start();
StreamReader soStream = process.StandardOutput;
string output = soStream.ReadToEnd();
return process.ExitCode is not 0 ? new DataOrException<List<PRC>>(new Exception($"Netstat result is {process.ExitCode}, expected 0")) : new DataOrException<List<PRC>>((from line in newlineRegex.Split(output) where !line.Trim().StartsWith("Proto") select line.Split(' ', StringSplitOptions.RemoveEmptyEntries) into parts let len = parts.Length where len > 2 select new PRC { Protocol = parts[0], Port = int.Parse(parts[1].Split(':').Last()), PID = int.Parse(parts[len - 1]) }).ToList());
}
}