Диспетчер задач на с++

107
25 февраля 2022, 18:50

пишу курсовую работу(диспетчер задач) не могу вывести список действующих процессов в листбокс. В документации по visual studio 2019 я не могу найти как это реализовать, а в коде с других форумов путаюсь. Можете поделиться кусочком кода, а ещё лутше если объясните как реализовать.

Answer 1

Можно получить список процессов используя wtsapi32. API доступно с Windows XP

#include "Windows.h"
#include "WtsApi32.h"
WTS_PROCESS_INFO* pWPIs = NULL;
DWORD dwProcCount = 0;
if (WTSEnumerateProcesses(WTS_CURRENT_SERVER_HANDLE, NULL, 1, &pWPIs, &dwProcCount))
{
    for (DWORD i = 0; i < dwProcCount; i++) {
        std::wcout << pWPIs[i].pProcessName << std::endl;
    }
}
if (pWPIs)
{
    WTSFreeMemory(pWPIs);
}

Оригинальный ответ [EN SO]

Answer 2

Только недавно делал такое, правда в контексте поиска процесса с заданным именем файла. Имеется некоторая проблема - код написан на C++17.

#include <functional>
#include <iostream>
#include <windows.h>
#include <psapi.h>
using PIDVector=vector<DWORD>;
using HMODULEVector=vector<HMODULE>;
template<typename T> bool autoFill(T& vec,std::function<WINBOOL(typename T::value_type*, DWORD, DWORD*)> filler)
{
    //вычисляем размер одного элемента массива
    constexpr auto itmSize=sizeof(typename T::value_type);
    while(true)
    {
        DWORD cnt;
        const auto status=filler(vec.data(), vec.size()*itmSize, &cnt);
        if(!status)
        {
            //в случае ошибки, выходим
            return false;
        }
        //нам приходит размер данных в байтах, а нужно - в штуках
        const auto nItems=cnt/itmSize; 
        if(nItems>=vec.size())
        {
            //если буфер мал - увеличить
            vec.resize( nItems + 1024);
        }
        else
        {
            vec.resize( nItems );
            return true;
        }
    }
}
void findProcess()
{
    const auto fName=procName.toUpper();   
    PIDVector pids(1024);
    //вызываем заполнялку первый раз, в качестве функции-заполнителя выступает EnumProcesses
    if(!autoFill<PIDVector>(pids, &EnumProcesses))
    {
        return;
    }
    wcout << pids.size() << L" processes found";

    for(const auto& i:pids)
    {    
        const auto cur=OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ,FALSE,i);
        if(!cur)
        {
            lout.fail();
            continue;
        }

        wstring name;
        //второй раз сложнее - GetProcessImageFileNameW работает по тому же шаблону, что и EnumProcesses, но аргументы принимает иначе
        //справляемся с этим, затолкав ее в адаптер из функтора
        autoFill(name,[cur](wchar_t* str,DWORD size,DWORD* needed)
                         {
                             *needed=GetProcessImageFileNameW(cur,str,size/sizeof(wchar_t))*sizeof(wchar_t);
                             return TRUE;
                         }
                );    
        wcout << name;
    }
    return;
}

Магия с шаблоном тут сделана потому, что нужно дважды делать вызов функции с одинаковым паттерном

  • вызывать
  • проверить, что функции хватило буфера
  • если нехватило, повторить

Чтобы не писать два раза идентичный по форме код, я сочинил шаблон.

READ ALSO
Не прорисовывается карта в игре на c++

Не прорисовывается карта в игре на c++

У меня есть массив строк, который и является картой:

90
Есть ли в Boost парсер математических выражений?

Есть ли в Boost парсер математических выражений?

Чтобы отправить строку с выражением с переменными и получить результат

75
Как правильно разбивать программу на модули в C++?

Как правильно разбивать программу на модули в C++?

К примеру у меня есть проект на Qt, есть maincpp, mainform

83
static в глобальной области видимости

static в глобальной области видимости

Если я объявляю static-функцию в глобальной области видимости, то она доступна только в этом файле, и её extern уже не получитьЕсли static-переменная...

61