使用命令行获取进程 ID

Getting ProcessId with CommandLine

我已经在这里搜索了答案,但找不到任何有效的代码片段或提示。

如何使用给定的命令行获取 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 的 CommandLine。 但我想要给定命令行的 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 循环开始时停止:"Query invalid" 任何人都可以帮助我进行这样的查询以通过 CommandLine 获取 ProcessId 吗? 提前致谢!

编辑: 我需要这个作为进程看门狗。我有 4 个以参数开头的程序。但是在它们开始之前不应该有这些程序的任何实例。所以我的尝试是启动每个进程,获取进程的 CommandLine(上面的 GetCommandLine),终止进程,然后我想搜索具有相同 CommandLine 的进程以终止它们。只有完成此操作后,我才能启动我的 4 个程序而不会惊慌失措。这就是为什么我需要一种通过命令行提取 processIds 的方法。

也许这对你有用。

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 { }
    }
}

也尝试使用范围参数。

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 Whosebug answer。这将允许您立即获取进程 ID 和命令行,而无需枚举响应并多次调用数据库。