使用命令行获取进程 ID
Posted
技术标签:
【中文标题】使用命令行获取进程 ID【英文标题】:Getting ProcessId with CommandLine 【发布时间】:2018-09-12 14:07:19 【问题描述】:我已经在这里搜索了答案,但找不到任何有效的代码 sn-ps 或提示。
如何使用给定的命令行获取 ProcessId?我已经用这个方法通过 Pid 获得了 CommandLine:
private IEnumerable<string> GetCommandLine(Process process)
using (ManagementObjectSearcher searcher = new ManagementObjectSearcher("SELECT CommandLine FROM Win32_Process WHERE ProcessId = " + process.Id))
using (ManagementObjectCollection objects = searcher.Get())
foreach (var element in objects)
yield return element["CommandLine"]?.ToString();
这适用于获取具有给定 ProcessId 的命令行。 但我想要带有给定命令行的 ProcessId。 我开始了一个进程,其中包含我正在搜索的这个命令行。 这是我的尝试:
private IEnumerable<int> GetIdsByCommandLine(string commandLine)
using (ManagementObjectSearcher searcher = new ManagementObjectSearcher("SELECT ProcessID FROM Win32_Process WHERE CommandLine = " + commandLine))
using (ManagementObjectCollection objects = searcher.Get())
foreach (var element in objects)
yield return (int) element["ProcessId"];
但如果我运行它,它会在 foreach 循环的开始处停止:“查询无效” 任何人都可以通过这样的查询帮助我通过命令行获取 ProcessId 吗? 提前致谢!
编辑: 我需要这个作为进程看门狗。我有 4 个以参数开头的程序。但是在它们开始之前不应该有这些程序的任何实例。所以我的尝试是启动每个,获取进程的CommandLine(上面的GetCommandLine),杀死进程,然后我想搜索具有相同CommandLine的进程来杀死它们。只有完成此操作后,我才能启动我的 4 个程序,而不会让它们四处乱窜。这就是为什么我需要一种通过命令行提取 processIds 的方法。
【问题讨论】:
试试看a similar *** question。 是否像在第二个示例中需要引用字符串一样简单?首先,您不需要在 pid 周围加上引号,因为它是数字的。在命令行的情况下,虽然它是一个字符串,所以可能需要被引用。我从来没有使用过这项技术,所以不确定,但鉴于它是类似 SQL 的语法,我认为这是一个合理的猜测...... @Chris 这听起来很合理,你知道这会是什么样子吗? @csharpforevermore 与 Name 和 ProcessId 没有问题。这些查询也对我有用。但是我需要命令行的过程,在我的帖子上查看我的编辑,这解释了原因。不过谢谢你的回答。 @JayBeAl:好吧,如果所有其他方法都失败了,您可能只是删除 WHERE,然后使用 LINQ 在内存中检查您想要的东西。也会使调试更容易。 :) 【参考方案1】:也尝试使用范围参数。
private IEnumerable<int> GetIdsByCommandLine(string commandLine)
string queryString = "SELECT ProcessID FROM Win32_Process WHERE CommandLine = " + commandLine;
string wmiScope = @"\\your_computer_name\root\cimv2";
using (ManagementObjectSearcher searcher = new ManagementObjectSearcher(wmiScope, queryString))
using (ManagementObjectCollection objects = searcher.Get())
foreach (ManagementBaseObject element in objects)
yield return (int)element["ProcessId"];
请记住,命令行会根据进程的调用方式而有所不同,因此这不是 100% 可靠的。我假设您将一次传递一个字符串列表,从GetCommandLine()
到GetIdsByCommandLine()
?
这是没有意义的,因为您只需将上面的 queryString 参数更改为
string queryString = "SELECT Name, CommandLine, ProcessId, Caption, ExecutablePath FROM Win32_Process";
根据this *** answer。这将允许您一次获取进程 ID 和命令行,而无需枚举响应并多次调用数据库。
【讨论】:
这和@Chris 在我的帖子中的第三条评论帮助了我。我现在只需使用 ProcessId 和 CommandLine 获取对象,然后使用 Linq 来获取我想要的。谢谢! 很高兴它有帮助。感谢您选择我的答案。祝你好运!【参考方案2】:也许这对你有用。
using System.Diagnostics;
public class KillProcess
[DllImport("user32.dll")]
static extern int GetWindowThreadProcessId(int hWnd, out int lpdwProcessId);
Process _KillProcess(int Hwnd)
int id;
GetWindowThreadProcessId(Hwnd, out id);
Process _Process = Process.GetProcessById(id);
_Process.Kill();
另外,另一种方式是
System.Diagnostics.Process[] process = System.Diagnostics.Process.GetProcessesByName("Excel");
foreach (System.Diagnostics.Process p in process)
if (!string.IsNullOrEmpty(p.ProcessName))
try
p.Kill();
catch
【讨论】:
这看起来不像是回答了这个问题。 OP 想要查找给定命令行的进程,而不是名称。 是的@Rup 是对的,我无法使用这些名称,我需要命令行中的 processId。不过谢谢以上是关于使用命令行获取进程 ID的主要内容,如果未能解决你的问题,请参考以下文章
如何在 PowerShell 或 C# 中获取进程的命令行信息