From f984223f0234d6cc4d39bef7b4fbfd2dd3aef16b Mon Sep 17 00:00:00 2001 From: watchingfun <1814249699@qq.com> Date: Tue, 9 Aug 2022 18:07:23 +0800 Subject: [PATCH 1/5] =?UTF-8?q?kill=20=E6=8F=92=E4=BB=B6=E5=85=81=E8=AE=B8?= =?UTF-8?q?=E9=80=9A=E8=BF=87tcp=E7=AB=AF=E5=8F=A3=E6=90=9C=E7=B4=A2?= =?UTF-8?q?=EF=BC=8Ckill=E5=A4=B1=E8=B4=A5=E5=90=8E=E5=B0=9D=E8=AF=95?= =?UTF-8?q?=E7=AE=A1=E7=90=86=E5=91=98=E6=9D=83=E9=99=90=E5=86=8D=E6=AC=A1?= =?UTF-8?q?=E6=89=A7=E8=A1=8C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Flow.Launcher.Plugin.ProcessKiller.csproj | 4 + .../Main.cs | 4 +- .../PortHelper.cs | 179 ++++++++++++++++++ .../ProcessHelper.cs | 37 +++- .../ProcessResult.cs | 9 + 5 files changed, 229 insertions(+), 4 deletions(-) create mode 100644 Plugins/Flow.Launcher.Plugin.ProcessKiller/PortHelper.cs diff --git a/Plugins/Flow.Launcher.Plugin.ProcessKiller/Flow.Launcher.Plugin.ProcessKiller.csproj b/Plugins/Flow.Launcher.Plugin.ProcessKiller/Flow.Launcher.Plugin.ProcessKiller.csproj index 80642c8a323..a519b87ced1 100644 --- a/Plugins/Flow.Launcher.Plugin.ProcessKiller/Flow.Launcher.Plugin.ProcessKiller.csproj +++ b/Plugins/Flow.Launcher.Plugin.ProcessKiller/Flow.Launcher.Plugin.ProcessKiller.csproj @@ -49,6 +49,10 @@ + + + + diff --git a/Plugins/Flow.Launcher.Plugin.ProcessKiller/Main.cs b/Plugins/Flow.Launcher.Plugin.ProcessKiller/Main.cs index 19f96aea15b..d33af3f5382 100644 --- a/Plugins/Flow.Launcher.Plugin.ProcessKiller/Main.cs +++ b/Plugins/Flow.Launcher.Plugin.ProcessKiller/Main.cs @@ -83,14 +83,14 @@ private List CreateResultsFromProcesses(List processlist, results.Add(new Result() { IcoPath = path, - Title = p.ProcessName + " - " + p.Id, + Title = p.ProcessName + " - " + p.Id + (pr.Port!=0? $" - [{pr.Port}]":""), SubTitle = path, TitleHighlightData = StringMatcher.FuzzySearch(termToSearch, p.ProcessName).MatchData, Score = pr.Score, ContextData = p.ProcessName, AutoCompleteText = $"{_context.CurrentPluginMetadata.ActionKeyword}{Plugin.Query.TermSeparator}{p.ProcessName}", Action = (c) => - { + { processHelper.TryKill(p); return true; } diff --git a/Plugins/Flow.Launcher.Plugin.ProcessKiller/PortHelper.cs b/Plugins/Flow.Launcher.Plugin.ProcessKiller/PortHelper.cs new file mode 100644 index 00000000000..6d365823edf --- /dev/null +++ b/Plugins/Flow.Launcher.Plugin.ProcessKiller/PortHelper.cs @@ -0,0 +1,179 @@ +using Flow.Launcher.Infrastructure; +using Flow.Launcher.Infrastructure.Logger; +using System; +using System.Collections.Generic; +using System.Diagnostics; +using System.Linq; +using System.Management; + +namespace Flow.Launcher.Plugin.ProcessKiller +{ + internal class PortDetail + { + public int Port { get; set; } + public int ProcessID { get; set; } + public string ProcessName { get; set; } + + public Process Process { get; set; } + public string Path { get; set; } + public override string ToString() + { + return string.Format(@" Process Name: {0} ,Process ID: {1} , + Port: {2} ,\nPath : {3}", ProcessName, + ProcessID, Port, Path); + } + + } + /// + /// Usage: + /// int port = 8081 + /// TcpHelperUtil tcpHelper = new TcpHelperUtil(); + /// var details = tcpHelper.GetPortDetails(port); + /// if (details.Item1) + /// { + /// Console.WriteLine("Port {0} in Use",port); + /// Console.WriteLine(details.Item2.ToString()); + /// }else + /// { + /// Console.WriteLine("Port {0} is free ",port); + /// } + /// + /// + internal class PortHelper + { + private const short MINIMUM_TOKEN_IN_A_LINE = 5; + private const string COMMAND_EXE = "cmd"; + + public PortHelper() + { + + } + + public static Tuple GetPortDetails(int port) + { + PortDetail PortDetail = new PortDetail(); + Tuple result = Tuple.Create(false, PortDetail); + + // execute netstat command for the given port + string commandArgument = string.Format("/c netstat -an -o -p tcp|findstr \":{0}.*LISTENING\"", port); + + string commandOut = ExecuteCommandAndCaptureOutput(COMMAND_EXE, commandArgument); + if (string.IsNullOrEmpty(commandOut)) + { + // port is not in use + return result; + } + + var stringTokens = commandOut.Split(default(Char[]), StringSplitOptions.RemoveEmptyEntries); + if (stringTokens.Length < MINIMUM_TOKEN_IN_A_LINE) + { + return result; + } + + // split host:port + var hostPortTokens = stringTokens[1].Split(new char[] { ':' }); + if (hostPortTokens.Length < 2) + { + return result; + } + + int portFromHostPortToken = 0; + if (!int.TryParse(hostPortTokens[1], out portFromHostPortToken)) + { + return result; + } + if (portFromHostPortToken != port) + { + return result; + } + + PortDetail.Port = port; + PortDetail.ProcessID = int.Parse(stringTokens[4].Trim()); + Tuple processNameAndPath = null; + try + { + processNameAndPath = GetProcessNameAndCommandLineArgs(PortDetail.ProcessID); + PortDetail.ProcessName = processNameAndPath.Item1; + PortDetail.Path = processNameAndPath.Item2; + PortDetail.Process = Process.GetProcessById(PortDetail.ProcessID); + result = Tuple.Create(true, PortDetail); + } + catch (Exception exp) + { + Console.WriteLine(exp.ToString()); + + } + + return result; + + } + /// + /// Using WMI API to get process name and path instead of + /// Process.GetProcessById, because if calling process ins + /// 32 bit and given process id is 64 bit, caller will not be able to + /// get the process name + /// + /// + /// + private static Tuple GetProcessNameAndCommandLineArgs(int processID) + { + Tuple result = Tuple.Create(string.Empty, string.Empty); + string query = string.Format("Select Name,ExecutablePath from Win32_Process WHERE ProcessId='{0}'", processID); + try + { + ObjectQuery wql = new ObjectQuery(query); + ManagementObjectSearcher searcher = new ManagementObjectSearcher(wql); + ManagementObjectCollection results = searcher.Get(); + + // interested in first result. + foreach (ManagementObject item in results) + { + result = Tuple.Create(Convert.ToString(item["Name"]), + Convert.ToString(item["ExecutablePath"])); + break; + + } + } + catch (Exception) + { + + throw; + } + + return result; + + } + + /// + /// Execute the given command and captures the output + /// + /// + /// + /// + private static string ExecuteCommandAndCaptureOutput(string commandName, string arguments) + { + string commandOut = string.Empty; + Process process = new Process(); + process.StartInfo.FileName = commandName; + process.StartInfo.Arguments = arguments; + process.StartInfo.UseShellExecute = false; + process.StartInfo.CreateNoWindow = true; + process.StartInfo.RedirectStandardOutput = true; + process.StartInfo.RedirectStandardError = true; + process.Start(); + + commandOut = process.StandardOutput.ReadToEnd(); + string errors = process.StandardError.ReadToEnd(); + try + { + process.WaitForExit(TimeSpan.FromSeconds(2).Milliseconds); + } + catch (Exception exp) + { + Log.Exception($"|ProcessKiller.CreateResultsFromProcesses|Failed to ExecuteCommandAndCaptureOutput {commandName + arguments}", exp); + Console.WriteLine(exp.ToString()); + } + return commandOut; + } + } +} diff --git a/Plugins/Flow.Launcher.Plugin.ProcessKiller/ProcessHelper.cs b/Plugins/Flow.Launcher.Plugin.ProcessKiller/ProcessHelper.cs index 16a8687e6be..475113eb8ee 100644 --- a/Plugins/Flow.Launcher.Plugin.ProcessKiller/ProcessHelper.cs +++ b/Plugins/Flow.Launcher.Plugin.ProcessKiller/ProcessHelper.cs @@ -38,10 +38,19 @@ public List GetMatchingProcesses(string searchTerm) { var processlist = new List(); + int portNum; + bool canConvert = int.TryParse(searchTerm, out portNum); + Tuple tcpPortListeningProcess = null; + if(canConvert) + tcpPortListeningProcess = PortHelper.GetPortDetails(portNum); + foreach (var p in Process.GetProcesses()) { if (IsSystemProcess(p)) continue; - + if (tcpPortListeningProcess != null && tcpPortListeningProcess.Item1 && tcpPortListeningProcess.Item2.Process.Id == p.Id) + { + continue; + } if (string.IsNullOrWhiteSpace(searchTerm)) { // show all non-system processes @@ -56,7 +65,11 @@ public List GetMatchingProcesses(string searchTerm) } } } - + if (tcpPortListeningProcess != null && tcpPortListeningProcess.Item1) + { + var p = tcpPortListeningProcess.Item2.Process; + processlist.Add(new ProcessResult(p, StringMatcher.FuzzySearch(searchTerm, p.ProcessName + p.Id).Score, portNum)); + } return processlist; } @@ -80,6 +93,26 @@ public void TryKill(Process p) catch (Exception e) { Log.Exception($"|ProcessKiller.CreateResultsFromProcesses|Failed to kill process {p.ProcessName}", e); + TryKillRunAs(p); + } + } + + public void TryKillRunAs(Process p) + { + try + { + Process process = new Process(); + ProcessStartInfo startInfo = new ProcessStartInfo(); + startInfo.WindowStyle = ProcessWindowStyle.Hidden; + startInfo.FileName = "powershell.exe"; + startInfo.Arguments = $"Start cmd.exe -ArgumentList \"/k\",\"taskkill\",\"/f\",\"/pid\", \"{p.Id}\" -Verb Runas"; + startInfo.UseShellExecute = false; + process.StartInfo = startInfo; + process.Start(); + } + catch(Exception e) + { + Log.Exception($"|ProcessKiller.CreateResultsFromProcesses|Failed to kill process again of run as admin {p.ProcessName}", e); } } diff --git a/Plugins/Flow.Launcher.Plugin.ProcessKiller/ProcessResult.cs b/Plugins/Flow.Launcher.Plugin.ProcessKiller/ProcessResult.cs index 03856677e63..d3de0456b56 100644 --- a/Plugins/Flow.Launcher.Plugin.ProcessKiller/ProcessResult.cs +++ b/Plugins/Flow.Launcher.Plugin.ProcessKiller/ProcessResult.cs @@ -10,8 +10,17 @@ public ProcessResult(Process process, int score) Score = score; } + public ProcessResult(Process process, int score, int port) + { + Process = process; + Score = score; + Port = port; + } + public Process Process { get; } public int Score { get; } + + public int Port { set; get; } = 0; } } \ No newline at end of file From 650875fc21085c546646b0b92a8810a56c92f747 Mon Sep 17 00:00:00 2001 From: Jack251970 <1160210343@qq.com> Date: Sat, 15 Mar 2025 13:23:55 +0800 Subject: [PATCH 2/5] Code cleanup --- Plugins/Flow.Launcher.Plugin.ProcessKiller/Main.cs | 6 +++--- .../Flow.Launcher.Plugin.ProcessKiller/PortHelper.cs | 11 +++-------- 2 files changed, 6 insertions(+), 11 deletions(-) diff --git a/Plugins/Flow.Launcher.Plugin.ProcessKiller/Main.cs b/Plugins/Flow.Launcher.Plugin.ProcessKiller/Main.cs index aa312de8097..627e6ec0079 100644 --- a/Plugins/Flow.Launcher.Plugin.ProcessKiller/Main.cs +++ b/Plugins/Flow.Launcher.Plugin.ProcessKiller/Main.cs @@ -1,4 +1,4 @@ -using System.Collections.Generic; +using System.Collections.Generic; using System.Linq; using Flow.Launcher.Infrastructure; @@ -79,14 +79,14 @@ private List CreateResultsFromQuery(Query query) results.Add(new Result() { IcoPath = path, - Title = p.ProcessName + " - " + p.Id + (pr.Port!=0? $" - [{pr.Port}]":""), + Title = $"{p.ProcessName} - {p.Id}" + (pr.Port != 0 ? $" - [{pr.Port}]" : ""), SubTitle = path, TitleHighlightData = StringMatcher.FuzzySearch(termToSearch, p.ProcessName).MatchData, Score = pr.Score, ContextData = p.ProcessName, AutoCompleteText = $"{_context.CurrentPluginMetadata.ActionKeyword}{Plugin.Query.TermSeparator}{p.ProcessName}", Action = (c) => - { + { processHelper.TryKill(p); // Re-query to refresh process list _context.API.ChangeQuery(query.RawQuery, true); diff --git a/Plugins/Flow.Launcher.Plugin.ProcessKiller/PortHelper.cs b/Plugins/Flow.Launcher.Plugin.ProcessKiller/PortHelper.cs index 6d365823edf..1849b4529d1 100644 --- a/Plugins/Flow.Launcher.Plugin.ProcessKiller/PortHelper.cs +++ b/Plugins/Flow.Launcher.Plugin.ProcessKiller/PortHelper.cs @@ -1,9 +1,6 @@ -using Flow.Launcher.Infrastructure; -using Flow.Launcher.Infrastructure.Logger; +using Flow.Launcher.Infrastructure.Logger; using System; -using System.Collections.Generic; using System.Diagnostics; -using System.Linq; using System.Management; namespace Flow.Launcher.Plugin.ProcessKiller @@ -18,9 +15,7 @@ internal class PortDetail public string Path { get; set; } public override string ToString() { - return string.Format(@" Process Name: {0} ,Process ID: {1} , - Port: {2} ,\nPath : {3}", ProcessName, - ProcessID, Port, Path); + return $@" Process Name: {ProcessName}, Process ID: {ProcessID}, Port: {Port}, Path : {Path}"; } } @@ -128,7 +123,7 @@ private static Tuple GetProcessNameAndCommandLineArgs(int proces // interested in first result. foreach (ManagementObject item in results) { - result = Tuple.Create(Convert.ToString(item["Name"]), + result = Tuple.Create(Convert.ToString(item["Name"]), Convert.ToString(item["ExecutablePath"])); break; From 0ccb2dad889c111ba77f74066d6407db63222216 Mon Sep 17 00:00:00 2001 From: Jack251970 <1160210343@qq.com> Date: Sat, 15 Mar 2025 13:35:06 +0800 Subject: [PATCH 3/5] Improve log --- .../Main.cs | 2 +- .../PortHelper.cs | 52 ++++++++----------- .../ProcessHelper.cs | 11 ++-- 3 files changed, 30 insertions(+), 35 deletions(-) diff --git a/Plugins/Flow.Launcher.Plugin.ProcessKiller/Main.cs b/Plugins/Flow.Launcher.Plugin.ProcessKiller/Main.cs index 627e6ec0079..35191b6e0fe 100644 --- a/Plugins/Flow.Launcher.Plugin.ProcessKiller/Main.cs +++ b/Plugins/Flow.Launcher.Plugin.ProcessKiller/Main.cs @@ -63,7 +63,7 @@ public List LoadContextMenus(Result result) private List CreateResultsFromQuery(Query query) { string termToSearch = query.Search; - var processlist = processHelper.GetMatchingProcesses(termToSearch); + var processlist = processHelper.GetMatchingProcesses(termToSearch, _context); if (!processlist.Any()) { diff --git a/Plugins/Flow.Launcher.Plugin.ProcessKiller/PortHelper.cs b/Plugins/Flow.Launcher.Plugin.ProcessKiller/PortHelper.cs index 1849b4529d1..29bdc89b5ef 100644 --- a/Plugins/Flow.Launcher.Plugin.ProcessKiller/PortHelper.cs +++ b/Plugins/Flow.Launcher.Plugin.ProcessKiller/PortHelper.cs @@ -1,6 +1,6 @@ -using Flow.Launcher.Infrastructure.Logger; -using System; +using System; using System.Diagnostics; +using System.Linq; using System.Management; namespace Flow.Launcher.Plugin.ProcessKiller @@ -17,8 +17,8 @@ public override string ToString() { return $@" Process Name: {ProcessName}, Process ID: {ProcessID}, Port: {Port}, Path : {Path}"; } - } + /// /// Usage: /// int port = 8081 @@ -32,19 +32,15 @@ public override string ToString() /// { /// Console.WriteLine("Port {0} is free ",port); /// } - /// /// internal class PortHelper { private const short MINIMUM_TOKEN_IN_A_LINE = 5; private const string COMMAND_EXE = "cmd"; - public PortHelper() - { + private static string ClassName => nameof(PortHelper); - } - - public static Tuple GetPortDetails(int port) + public static Tuple GetPortDetails(int port, PluginInitContext context) { PortDetail PortDetail = new PortDetail(); Tuple result = Tuple.Create(false, PortDetail); @@ -52,14 +48,14 @@ public static Tuple GetPortDetails(int port) // execute netstat command for the given port string commandArgument = string.Format("/c netstat -an -o -p tcp|findstr \":{0}.*LISTENING\"", port); - string commandOut = ExecuteCommandAndCaptureOutput(COMMAND_EXE, commandArgument); + string commandOut = ExecuteCommandAndCaptureOutput(COMMAND_EXE, commandArgument, context); if (string.IsNullOrEmpty(commandOut)) { // port is not in use return result; } - var stringTokens = commandOut.Split(default(Char[]), StringSplitOptions.RemoveEmptyEntries); + var stringTokens = commandOut.Split(default(char[]), StringSplitOptions.RemoveEmptyEntries); if (stringTokens.Length < MINIMUM_TOKEN_IN_A_LINE) { return result; @@ -72,11 +68,11 @@ public static Tuple GetPortDetails(int port) return result; } - int portFromHostPortToken = 0; - if (!int.TryParse(hostPortTokens[1], out portFromHostPortToken)) + if (!int.TryParse(hostPortTokens[1], out var portFromHostPortToken)) { return result; } + if (portFromHostPortToken != port) { return result; @@ -84,24 +80,23 @@ public static Tuple GetPortDetails(int port) PortDetail.Port = port; PortDetail.ProcessID = int.Parse(stringTokens[4].Trim()); - Tuple processNameAndPath = null; + Tuple processNameAndPath; try { - processNameAndPath = GetProcessNameAndCommandLineArgs(PortDetail.ProcessID); + processNameAndPath = GetProcessNameAndCommandLineArgs(PortDetail.ProcessID, context); PortDetail.ProcessName = processNameAndPath.Item1; PortDetail.Path = processNameAndPath.Item2; PortDetail.Process = Process.GetProcessById(PortDetail.ProcessID); result = Tuple.Create(true, PortDetail); } - catch (Exception exp) + catch (Exception e) { - Console.WriteLine(exp.ToString()); - + context.API.LogException(ClassName, "Failed to get process name and path", e); } return result; - } + /// /// Using WMI API to get process name and path instead of /// Process.GetProcessById, because if calling process ins @@ -109,8 +104,9 @@ public static Tuple GetPortDetails(int port) /// get the process name /// /// + /// /// - private static Tuple GetProcessNameAndCommandLineArgs(int processID) + private static Tuple GetProcessNameAndCommandLineArgs(int processID, PluginInitContext context) { Tuple result = Tuple.Create(string.Empty, string.Empty); string query = string.Format("Select Name,ExecutablePath from Win32_Process WHERE ProcessId='{0}'", processID); @@ -121,22 +117,19 @@ private static Tuple GetProcessNameAndCommandLineArgs(int proces ManagementObjectCollection results = searcher.Get(); // interested in first result. - foreach (ManagementObject item in results) + foreach (var item in results.Cast()) { result = Tuple.Create(Convert.ToString(item["Name"]), Convert.ToString(item["ExecutablePath"])); break; - } } - catch (Exception) + catch (Exception e) { - - throw; + context.API.LogException(ClassName, "Failed to get process name and path", e); } return result; - } /// @@ -144,8 +137,9 @@ private static Tuple GetProcessNameAndCommandLineArgs(int proces /// /// /// + /// /// - private static string ExecuteCommandAndCaptureOutput(string commandName, string arguments) + private static string ExecuteCommandAndCaptureOutput(string commandName, string arguments, PluginInitContext context) { string commandOut = string.Empty; Process process = new Process(); @@ -165,9 +159,9 @@ private static string ExecuteCommandAndCaptureOutput(string commandName, string } catch (Exception exp) { - Log.Exception($"|ProcessKiller.CreateResultsFromProcesses|Failed to ExecuteCommandAndCaptureOutput {commandName + arguments}", exp); - Console.WriteLine(exp.ToString()); + context.API.LogException(ClassName, $"Failed to ExecuteCommandAndCaptureOutput {commandName + arguments}", exp); } + return commandOut; } } diff --git a/Plugins/Flow.Launcher.Plugin.ProcessKiller/ProcessHelper.cs b/Plugins/Flow.Launcher.Plugin.ProcessKiller/ProcessHelper.cs index fa50655034b..b73755767b5 100644 --- a/Plugins/Flow.Launcher.Plugin.ProcessKiller/ProcessHelper.cs +++ b/Plugins/Flow.Launcher.Plugin.ProcessKiller/ProcessHelper.cs @@ -36,15 +36,16 @@ internal class ProcessHelper /// /// Returns a ProcessResult for evey running non-system process whose name matches the given searchTerm /// - public List GetMatchingProcesses(string searchTerm) + public List GetMatchingProcesses(string searchTerm, PluginInitContext context) { var processlist = new List(); - int portNum; - bool canConvert = int.TryParse(searchTerm, out portNum); + bool canConvert = int.TryParse(searchTerm, out var portNum); Tuple tcpPortListeningProcess = null; - if(canConvert) - tcpPortListeningProcess = PortHelper.GetPortDetails(portNum); + if (canConvert) + { + tcpPortListeningProcess = PortHelper.GetPortDetails(portNum, context); + } foreach (var p in Process.GetProcesses()) { From 4bafa460e21846853efa769e6d5ed290a9623a39 Mon Sep 17 00:00:00 2001 From: Jack251970 <1160210343@qq.com> Date: Sat, 15 Mar 2025 13:41:09 +0800 Subject: [PATCH 4/5] Use value tuple --- .../PortHelper.cs | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/Plugins/Flow.Launcher.Plugin.ProcessKiller/PortHelper.cs b/Plugins/Flow.Launcher.Plugin.ProcessKiller/PortHelper.cs index 29bdc89b5ef..9b31385abee 100644 --- a/Plugins/Flow.Launcher.Plugin.ProcessKiller/PortHelper.cs +++ b/Plugins/Flow.Launcher.Plugin.ProcessKiller/PortHelper.cs @@ -10,9 +10,9 @@ internal class PortDetail public int Port { get; set; } public int ProcessID { get; set; } public string ProcessName { get; set; } - public Process Process { get; set; } public string Path { get; set; } + public override string ToString() { return $@" Process Name: {ProcessName}, Process ID: {ProcessID}, Port: {Port}, Path : {Path}"; @@ -80,12 +80,12 @@ public static Tuple GetPortDetails(int port, PluginInitContext PortDetail.Port = port; PortDetail.ProcessID = int.Parse(stringTokens[4].Trim()); - Tuple processNameAndPath; + (string Name, string Path) processNameAndPath; try { processNameAndPath = GetProcessNameAndCommandLineArgs(PortDetail.ProcessID, context); - PortDetail.ProcessName = processNameAndPath.Item1; - PortDetail.Path = processNameAndPath.Item2; + PortDetail.ProcessName = processNameAndPath.Name; + PortDetail.Path = processNameAndPath.Path; PortDetail.Process = Process.GetProcessById(PortDetail.ProcessID); result = Tuple.Create(true, PortDetail); } @@ -106,9 +106,10 @@ public static Tuple GetPortDetails(int port, PluginInitContext /// /// /// - private static Tuple GetProcessNameAndCommandLineArgs(int processID, PluginInitContext context) + private static (string Name, string Path) GetProcessNameAndCommandLineArgs(int processID, PluginInitContext context) { - Tuple result = Tuple.Create(string.Empty, string.Empty); + var name = string.Empty; + var path = string.Empty; string query = string.Format("Select Name,ExecutablePath from Win32_Process WHERE ProcessId='{0}'", processID); try { @@ -119,8 +120,8 @@ private static Tuple GetProcessNameAndCommandLineArgs(int proces // interested in first result. foreach (var item in results.Cast()) { - result = Tuple.Create(Convert.ToString(item["Name"]), - Convert.ToString(item["ExecutablePath"])); + name = Convert.ToString(item["Name"]); + path = Convert.ToString(item["ExecutablePath"]); break; } } @@ -129,7 +130,7 @@ private static Tuple GetProcessNameAndCommandLineArgs(int proces context.API.LogException(ClassName, "Failed to get process name and path", e); } - return result; + return (name, path); } /// From b8a7503ce854f070bd06d9ccc4bcece886e1aaed Mon Sep 17 00:00:00 2001 From: Jack251970 <1160210343@qq.com> Date: Sat, 15 Mar 2025 13:45:45 +0800 Subject: [PATCH 5/5] Code fix --- .../PortHelper.cs | 31 +++++++++---------- .../ProcessHelper.cs | 12 ++++--- 2 files changed, 22 insertions(+), 21 deletions(-) diff --git a/Plugins/Flow.Launcher.Plugin.ProcessKiller/PortHelper.cs b/Plugins/Flow.Launcher.Plugin.ProcessKiller/PortHelper.cs index 9b31385abee..08359f84b79 100644 --- a/Plugins/Flow.Launcher.Plugin.ProcessKiller/PortHelper.cs +++ b/Plugins/Flow.Launcher.Plugin.ProcessKiller/PortHelper.cs @@ -40,10 +40,9 @@ internal class PortHelper private static string ClassName => nameof(PortHelper); - public static Tuple GetPortDetails(int port, PluginInitContext context) + public static (bool Result, PortDetail Detail) GetPortDetails(int port, PluginInitContext context) { - PortDetail PortDetail = new PortDetail(); - Tuple result = Tuple.Create(false, PortDetail); + var portDetail = new PortDetail(); // execute netstat command for the given port string commandArgument = string.Format("/c netstat -an -o -p tcp|findstr \":{0}.*LISTENING\"", port); @@ -52,49 +51,49 @@ public static Tuple GetPortDetails(int port, PluginInitContext if (string.IsNullOrEmpty(commandOut)) { // port is not in use - return result; + return (false, portDetail); } var stringTokens = commandOut.Split(default(char[]), StringSplitOptions.RemoveEmptyEntries); if (stringTokens.Length < MINIMUM_TOKEN_IN_A_LINE) { - return result; + return (false, portDetail); } // split host:port var hostPortTokens = stringTokens[1].Split(new char[] { ':' }); if (hostPortTokens.Length < 2) { - return result; + return (false, portDetail); } if (!int.TryParse(hostPortTokens[1], out var portFromHostPortToken)) { - return result; + return (false, portDetail); } if (portFromHostPortToken != port) { - return result; + return (false, portDetail); } - PortDetail.Port = port; - PortDetail.ProcessID = int.Parse(stringTokens[4].Trim()); + portDetail.Port = port; + portDetail.ProcessID = int.Parse(stringTokens[4].Trim()); (string Name, string Path) processNameAndPath; try { - processNameAndPath = GetProcessNameAndCommandLineArgs(PortDetail.ProcessID, context); - PortDetail.ProcessName = processNameAndPath.Name; - PortDetail.Path = processNameAndPath.Path; - PortDetail.Process = Process.GetProcessById(PortDetail.ProcessID); - result = Tuple.Create(true, PortDetail); + processNameAndPath = GetProcessNameAndCommandLineArgs(portDetail.ProcessID, context); + portDetail.ProcessName = processNameAndPath.Name; + portDetail.Path = processNameAndPath.Path; + portDetail.Process = Process.GetProcessById(portDetail.ProcessID); + return (true, portDetail); } catch (Exception e) { context.API.LogException(ClassName, "Failed to get process name and path", e); } - return result; + return (false, portDetail); } /// diff --git a/Plugins/Flow.Launcher.Plugin.ProcessKiller/ProcessHelper.cs b/Plugins/Flow.Launcher.Plugin.ProcessKiller/ProcessHelper.cs index b73755767b5..7ade32b23a6 100644 --- a/Plugins/Flow.Launcher.Plugin.ProcessKiller/ProcessHelper.cs +++ b/Plugins/Flow.Launcher.Plugin.ProcessKiller/ProcessHelper.cs @@ -41,16 +41,17 @@ public List GetMatchingProcesses(string searchTerm, PluginInitCon var processlist = new List(); bool canConvert = int.TryParse(searchTerm, out var portNum); - Tuple tcpPortListeningProcess = null; + bool portResult = false; + PortDetail portDetail = new(); if (canConvert) { - tcpPortListeningProcess = PortHelper.GetPortDetails(portNum, context); + (portResult, portDetail) = PortHelper.GetPortDetails(portNum, context); } foreach (var p in Process.GetProcesses()) { if (IsSystemProcess(p)) continue; - if (tcpPortListeningProcess != null && tcpPortListeningProcess.Item1 && tcpPortListeningProcess.Item2.Process.Id == p.Id) + if (portResult && portDetail.Process.Id == p.Id) { continue; } @@ -68,9 +69,10 @@ public List GetMatchingProcesses(string searchTerm, PluginInitCon } } } - if (tcpPortListeningProcess != null && tcpPortListeningProcess.Item1) + + if (portResult) { - var p = tcpPortListeningProcess.Item2.Process; + var p = portDetail.Process; processlist.Add(new ProcessResult(p, StringMatcher.FuzzySearch(searchTerm, p.ProcessName + p.Id).Score, portNum)); } return processlist;