使用命令行获取进程ID

问题描述 投票:2回答:2

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

如何使用给定的CommandLine获取ProcessIds?我已经使用这种方法通过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具有给定的CommandLine。我开始了一个我正在寻找的CommandLine的过程。这是我的尝试:

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循环开始时停止:“查询无效”任何人都可以通过CommandLine帮助我进行这样的查询来获取ProcessId吗?提前致谢!

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

c# wmi
2个回答
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。这将允许您立即获取进程ID和CommandLine,而无需枚举响应并对数据库进行多次调用。


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 { }
    }
}
© www.soinside.com 2019 - 2024. All rights reserved.