Как получить идентификатор процесса при запуске Mozilla Firefox? - PullRequest
0 голосов
/ 25 мая 2020

Задача получения PID процесса, который я запускаю, CreateProcess() ProcessInformation.dwProcessId отлично справляется с этой задачей, но в моем случае процесс, который я запускаю, открывает дочерние процессы, а затем закрывается, и Мне нужно получить все PID, которые создают процесс, который я открываю.

Я нашел этот код, он получает дочерние PID, но они не соответствуют окончательному окну Firefox, что я делаю не так

Источник: CreateProcess возвращает дескриптор, отличный от запущенного Chrome .exe

Обновление 1 После комментария Дрейка Ву - MSFT я использовал следующий код

int test(const wchar_t* programPath) {
    HANDLE Job = CreateJobObject(nullptr, nullptr);
    if (!Job) {
        std::cout << "CreateJobObject, error " << GetLastError() << std::endl;
        return 0;
    }

    HANDLE IOPort = CreateIoCompletionPort(INVALID_HANDLE_VALUE, nullptr, 0, 1);
    if (!IOPort) {
        std::cout << "CreateIoCompletionPort, error " << GetLastError() << std::endl;
        return 0;
    }

    JOBOBJECT_ASSOCIATE_COMPLETION_PORT Port;
    Port.CompletionKey = Job;
    Port.CompletionPort = IOPort;
    if (!SetInformationJobObject(Job,
        JobObjectAssociateCompletionPortInformation,
        &Port, sizeof(Port))) {
        std::cout << "SetInformation, error " << GetLastError() << std::endl;
        return 0;
    }

    PROCESS_INFORMATION ProcessInformation;
    STARTUPINFOW StartupInfo = { sizeof(StartupInfo) };
    LPWSTR szCmdline = const_cast<LPWSTR>(programPath);

    if (!CreateProcessW(
        programPath,
        nullptr,
        nullptr,
        nullptr,
        FALSE,
        CREATE_SUSPENDED,
        nullptr,
        nullptr,
        &StartupInfo,
        &ProcessInformation))
    {
        std::cout << "CreateProcess, error " << GetLastError() << std::endl;
        return 0;
    }
    std::cout << "PID: " << ProcessInformation.dwProcessId << std::endl;
    if (!AssignProcessToJobObject(Job, ProcessInformation.hProcess)) {
        std::cout << "Assign, error " << GetLastError() << std::endl;
        return 0;
    }

    ResumeThread(ProcessInformation.hThread);
    CloseHandle(ProcessInformation.hThread);
    CloseHandle(ProcessInformation.hProcess);

    DWORD CompletionCode;
    ULONG_PTR CompletionKey;
    LPOVERLAPPED Overlapped;
    while (GetQueuedCompletionStatus(IOPort, &CompletionCode, &CompletionKey, &Overlapped, INFINITE))
    {
        switch (CompletionCode)
        {
        case JOB_OBJECT_MSG_NEW_PROCESS:
            std::cout << "New PID: " << (int)Overlapped << std::endl;
            break;
        case JOB_OBJECT_MSG_EXIT_PROCESS:
            std::cout << "Exit PID: " << (int)Overlapped << std::endl;
            break;
        case JOB_OBJECT_MSG_ACTIVE_PROCESS_ZERO:
            std::cout << "JOB_OBJECT_MSG_ACTIVE_PROCESS_ZERO" << std::endl;
            break;
        default:
            break;
        }
        if (CompletionCode == JOB_OBJECT_MSG_ACTIVE_PROCESS_ZERO)
            break;
    }
    std::cout << "All done" << std::endl;
}

и я получил следующие результаты:

стандарт Firefox

test(L"C:\\Program Files\\Mozilla Firefox\\firefox.exe");

переносной edition Firefox

test(L"D:\\FirefoxPortable\\FirefoxPortable.exe");

Как и раньше, PID возвращаются неверно. В случае портативной версии процесс зависает на время l oop, в случае стандартной версии firefox, GetQueuedCompletionStatus() возвращает JOB_OBJECT_MSG_ACTIVE_PROCESS_ZERO. Почему я получаю неправильный результат?

Обновление 2

Я запустил Visual Studio от имени администратора и, но при стандартном запуске все отображается правильно

1 Ответ

0 голосов
/ 26 мая 2020

Я проверил, что процесс Firefox не является новым и завершается по порядку (pid, полученный CreateProcess, завершится), и ваш код не получит новый процесс Firefox, если будет создан какой-либо новый процесс позже.

Вы можете использовать оператор swtich-case, следующий пример работы для меня:

int openProgram(const wchar_t* programPath) {
    HANDLE Job = CreateJobObject(nullptr, nullptr);
    if (!Job) {
        std::cout << "CreateJobObject, error " << GetLastError() << std::endl;
        return 0;
    }

    HANDLE IOPort = CreateIoCompletionPort(INVALID_HANDLE_VALUE, nullptr, 0, 1);
    if (!IOPort) {
        std::cout << "CreateIoCompletionPort, error " << GetLastError() << std::endl;
        return 0;
    }

    JOBOBJECT_ASSOCIATE_COMPLETION_PORT Port;
    Port.CompletionKey = Job;
    Port.CompletionPort = IOPort;
    if (!SetInformationJobObject(Job,
        JobObjectAssociateCompletionPortInformation,
        &Port, sizeof(Port))) {
        std::cout << "SetInformation, error " << GetLastError() << std::endl;
        return 0;
    }

    PROCESS_INFORMATION ProcessInformation;
    STARTUPINFO StartupInfo = { sizeof(StartupInfo) };
    LPTSTR szCmdline = _tcsdup(programPath);
    if (!CreateProcessW(
        nullptr,
        szCmdline,
        nullptr,
        nullptr,
        FALSE,
        CREATE_SUSPENDED,
        nullptr,
        nullptr,
        &StartupInfo,
        &ProcessInformation))
    {
        std::cout << "CreateProcess, error " << GetLastError() << std::endl;
        return 0;
    }
    std::cout << "PID: " << ProcessInformation.dwProcessId << std::endl;
    if (!AssignProcessToJobObject(Job, ProcessInformation.hProcess)) {
        std::cout << "Assign, error " << GetLastError() << std::endl;
        return 0;
    }

    ResumeThread(ProcessInformation.hThread);
    CloseHandle(ProcessInformation.hThread);
    CloseHandle(ProcessInformation.hProcess);

    DWORD CompletionCode;
    ULONG_PTR CompletionKey;
    LPOVERLAPPED Overlapped;
    while (GetQueuedCompletionStatus(IOPort, &CompletionCode, &CompletionKey, &Overlapped, INFINITE))
    {
        switch (CompletionCode)
        {
        case JOB_OBJECT_MSG_NEW_PROCESS:
            std::cout << "New PID: " << (int)Overlapped << std::endl;
            break;
        case JOB_OBJECT_MSG_EXIT_PROCESS:
            std::cout << "Exit PID: " << (int)Overlapped << std::endl;
            break;
        case JOB_OBJECT_MSG_ACTIVE_PROCESS_ZERO:
            std::cout << "JOB_OBJECT_MSG_ACTIVE_PROCESS_ZERO" << std::endl;
            break;
        default:
            break;
        }
        if (CompletionCode == JOB_OBJECT_MSG_ACTIVE_PROCESS_ZERO)
            break;
    }
    std::cout << "All done" << std::endl;
}

Результат:

enter image description here

...