Получение ProcessId с помощью CommandLine - PullRequest
0 голосов
/ 12 сентября 2018

Я уже искал здесь ответ, но не смог найти ни фрагментов, ни рабочих кодов.

Как мне получить ProcessIds с заданной CommandLine? Я уже получил CommandLine от Pid с этим методом:

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

Это работает для получения CommandLine с заданным ProcessId. Но я хочу ProcessId с данной 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: «Запрос недействителен» Кто-нибудь может мне помочь с таким запросом, чтобы получить ProcessId по CommandLine? Заранее спасибо!

Edit: Мне это нужно для контроля над процессом. У меня есть 4 программы, которые запускаются с аргументами. Но не должно быть никаких экземпляров этих программ до их запуска. Поэтому я пытаюсь запустить каждый из них, получить CommandLine (GetCommandLine выше) процесса, убить процесс, а затем я хочу найти процессы с той же CommandLine, чтобы убить их. Только когда это будет сделано, я смогу запустить свои 4 программы без суеты. Вот почему мне нужен именно способ извлечения идентификаторов процессов с помощью CommandLine.

Ответы [ 2 ]

0 голосов
/ 12 сентября 2018

Попробуйте также использовать параметр 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";

согласно этому ответу StackOverflow . Это позволит вам сразу получить Идентификатор процесса и Командную линию без необходимости перечислять ответы и совершать многочисленные вызовы в базу данных.

0 голосов
/ 12 сентября 2018

Может быть, это может быть полезно для вас.

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 { }
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...