通过命令行获取ProcessId

时间:2018-09-12 14:07:19

标签: c# wmi

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

如何使用给定的命令行获取ProcessId?我已经使用这种方法通过Pid获得了CommandLine:

std::variant

这适用于获取具有给定ProcessId的CommandLine。 但是我想要具有给定命令行的ProcessId。 我开始了一个要搜索的命令行程序。 这是我的尝试:

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();
    }
}

但是,如果运行此命令,它将停止在foreach循环的开头:“查询无效” 有人可以通过命令行查询这样的查询来帮助我吗? 预先感谢!

编辑: 我需要一个过程看门狗。我有4个以参数开头的程序。但是在启动这些程序之前,不应有任何实例。因此,我的尝试是启动每个进程,获取进程的CommandLine(上面的GetCommandLine),杀死进程,然后我要搜索具有相同CommandLine的进程以杀死它们。只有做到这一点,我才能启动我的4个程序,而不必担心。这就是为什么我需要一种确切的方法来通过CommandLine提取processId。

2 个答案:

答案 0 :(得分:0)

也许这对您有用。

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

答案 1 :(得分:0)

也尝试使用scope参数。

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 StackOverflow answer。这样一来,您就可以立即获取Process ID和CommandLine,而不必枚举响应并多次调用数据库。