Перейти к содержанию

c++ список процессов


Рекомендуемые сообщения

Здравствуйте.Я недавно сделал программу , получающую список процессов (Process32Next), но вместе с процессами она выводит и сервисы .Как можно исправить ?

Ссылка на комментарий
Поделиться на другие сайты

Привет! Между процессом и сервисом разница только в том, что у сервиса иначально нет окна и пользователь сам никак с ним не взаимодействует. Есть еще пара особенностей, конечно, но они не сильно меняют суть дела.

Ссылка на комментарий
Поделиться на другие сайты

15 минуту назад, keng сказал:

Привет! Между процессом и сервисом разница только в том, что у сервиса иначально нет окна и пользователь сам никак с ним не взаимодействует. Есть еще пара особенностей, конечно, но они не сильно меняют суть дела.

Здравствуйте keng , я вас знаю ^_^ Рад , что вы ответили .Но как можно программно отличить их ?Может быть OpenProcess при открытии сервиса вернёт false ?

Изменено пользователем ШАРИК
Ссылка на комментарий
Поделиться на другие сайты

Первое, что пришло в голову - это вызвать для каждого найденного функцию [GetClassLong] и выяснить или иконку или адрес оконной процедуры. У сервиса ни первого, ни второго не окажется.

Ссылка на комментарий
Поделиться на другие сайты

9 минут назад, keng сказал:

Первое, что пришло в голову - это вызвать для каждого найденного функцию [GetClassLong] и выяснить или иконку или адрес оконной процедуры. У сервиса ни первого, ни второго не окажется.

А если считать кол-во сервисов и при выводе списка процессов первые несколько не выводить . Т.к. При выводе списка процессов , сначала выводятся сервисы.

Ссылка на комментарий
Поделиться на другие сайты

2 минуты назад, keng сказал:

Так ведь чтобы посчитать количество сервисов, для начала нужно научиться сервисы от обычных процессов отличать.

Не , есть специальная функция EnumServicesStatusEx Или не то ?(

Ссылка на комментарий
Поделиться на другие сайты

22 минуты назад, keng сказал:

Мой вариант с GetClassLong не сработал?

Мне кажется , что это не совсем то ... Можно было бы сделать как тут или тут .
В первом меня раздражает то , то там заданно количество элементов массива . Ну чуть позже попробую разобраться ...

Ссылка на комментарий
Поделиться на другие сайты

Когда кажется - нужно пробовать. Получаешь список всех процессов, у каждого получаешь его pID, по нему - HANDLE главного окна, если его нет - то это сервис. Если есть, получаешь ID иконки, если ее нет - то это сервис. Все, что осталось - складываешь в массив\вектор\лист или что угодно еще.

Ссылка на комментарий
Поделиться на другие сайты

попробуй RegisterServiceCtrlHandlerEx если возвращает true, то сервис запущен. Функция обрабатывает запросы на остановку, выполнение сервиса.

Или OpenSCManage получи доступ к менеджеру сервисов, используй тут EnumServicesStatusEx в  аргументе lpServicesReturned будет количество сервисов,

ZLUT4iTqU28.jpg

Изменено пользователем partoftheworlD
Ссылка на комментарий
Поделиться на другие сайты

Неверно нужно сначала получить список сервисов и загрузить их id в вектор, а потом при получении списка процессов проверять функцией find , есть ли в векторе такой th32ProcessID.

Ссылка на комментарий
Поделиться на другие сайты

Получил , пока только один сервис , потому что я хз , как их перебирать.
Делал как тут , но массив заменил на (_SERVICE_STATUS_PROCESS   Services )
В общем так:
 

Скрытый текст

	  SC_HANDLE hSCManager = OpenSCManager(NULL, NULL, SC_MANAGER_ENUMERATE_SERVICE);
	  BOOL bSuccess = FALSE;
		  DWORD dwBytesNeeded = 0;
	DWORD dwServicesReturned = 0;
	DWORD dwResumeHandle = 0;

	DWORD dwServicesCount = 0;
	 _SERVICE_STATUS_PROCESS   Services ;

		bSuccess = EnumServicesStatusEx(hSCManager, SC_ENUM_PROCESS_INFO,
			SERVICE_WIN32, SERVICE_STATE_ALL, LPBYTE(&Services),
			sizeof(Services), &dwBytesNeeded, &dwServicesReturned,
			&dwResumeHandle, NULL);
			Form2->ListBox1->Items->Add(String(Services.dwProcessId));

 

Но чет через раз работает ... То показывает id 4 , то 0

Ссылка на комментарий
Поделиться на другие сайты

 _SERVICE_STATUS_PROCESS   Services ;

какой же это массив, это одна структура

 

 

и к тому же.. открываем MSDN и читаем

 

InfoLevel [in]
The service attributes that are to be returned. Use SC_ENUM_PROCESS_INFO to retrieve the name and service status information for each service in the database. The lpServices parameter is a pointer to a buffer that receives an array of ENUM_SERVICE_STATUS_PROCESS structures. The buffer must be large enough to hold the structures as well as the strings to which their members point.
Currently, no other information levels are defined.

Изменено пользователем Dino
Ссылка на комментарий
Поделиться на другие сайты

В 23.09.2016в18:39, keng сказал:

Когда кажется - нужно пробовать. Получаешь список всех процессов, у каждого получаешь его pID, по нему - HANDLE главного окна, если его нет - то это сервис. Если есть, получаешь ID иконки, если ее нет - то это сервис. Все, что осталось - складываешь в массив\вектор\лист или что угодно еще.

а если у приложения нет окна?

Ссылка на комментарий
Поделиться на другие сайты

15 hours ago, Dino said:

а если у приложения нет окна?

Для примера возьму Dropbox - у него нет окна в нормальном понимании этого слова, зато есть иконка. Как я уже писал выше, это - просто один из вариантов, что навскидку пришел в голову. Мне уже больше интересно, что за задача такая у автора темы.

Ссылка на комментарий
Поделиться на другие сайты

Если работает через раз, то проблема с кодом, а точнее с получением базы сервиса. Второй параметр должен принимать активную базу, при нуле часто может базу не определять.

 

Цитата

lpDatabaseName

[in] Указатель на строку с завершающим нулем, которая задает имя открываемой базы данных диспетчера управления службами. Этот параметр должен быть установлен вSERVICES_ACTIVE_DATABASE. Если это  значение ПУСТО (NULL), база данных SERVICES_ACTIVE_DATABASE открыта по умолчанию.

 

И третий параметр

Цитата

dwDesiredAccess

[in] Доступ к диспетчеру управления службами. Перечень прав доступа, см. в статье Защита службы и права доступа.

Перед предоставлением требуемых прав доступа, система проверяет маркер доступа вызывающего процесса опираясь на список разграничительного контроля доступа дескриптора безопасности, связанного с диспетчером управления службами.

Право доступа SC_MANAGER_CONNECT определяется неявно, путем вызова этой функции.

 

Скрытый текст

#include <windows.h>
#include <stdio.h>


int main()
{
	SC_HANDLE manager = OpenSCManager(NULL, SERVICES_ACTIVE_DATABASE, SC_MANAGER_CONNECT | SC_MANAGER_ENUMERATE_SERVICE);

	DWORD bytesNeeded = 0;
	DWORD servicesNum = 0;

	BOOL status = EnumServicesStatusEx(
		manager,
		SC_ENUM_PROCESS_INFO,
		SERVICE_WIN32,
		SERVICE_STATE_ALL,
		NULL,
		0,
		&bytesNeeded,
		&servicesNum,
		NULL,
		NULL
	);

	PBYTE lpBytes = (PBYTE)malloc(bytesNeeded);

	status = EnumServicesStatusEx(
		manager,
		SC_ENUM_PROCESS_INFO,
		SERVICE_WIN32,
		SERVICE_STATE_ALL,
		lpBytes,
		bytesNeeded,
		&bytesNeeded,
		&servicesNum,
		NULL,
		NULL
	);

	printf("Sevices count: %i\n", servicesNum);

	free(lpBytes);

	return 0;
}

 

 

Изменено пользователем partoftheworlD
Ссылка на комментарий
Поделиться на другие сайты

Короче , я либо не туда копаю , либо что-то не так делаю .
Нужно получить список процессов без smss.exe , svchost и т.д.
 

Скрытый текст

JDHxsYYMpIM.jpg

 

Ссылка на комментарий
Поделиться на другие сайты

Spoiler

format PE console

include 'c:\stuff\soft\fasm\include\win32a.inc'

section '.text' code readable executable
entry $
  invoke OpenSCManager,0,0,0x4                                                   ; Менеджер сервисов хочу!
  MOV    [svcHandle],EAX                                                         ; scvHandle - хэндл менеджера сервисов
  invoke EnumServicesStatusEx,EAX,0,0x30,0x3,0,0,needed,num,0,0                  ; Знать размер всех сервисов хочу!
  invoke VirtualAlloc,0,[needed],0x3000,0x4                                      ; Памяти под сервисы хочу!
  MOV    [svcList],EAX                                                           ; svcList - там все сервисы лежат!
  invoke EnumServicesStatusEx,[svcHandle],0,0x30,0x3,EAX,[needed],needed,num,0,0 ; Знать все про сервисы хочу!
  invoke VirtualAlloc,0,1024*4,0x3000,0x4                                        ; Памяти под процессы хочу!
  MOV    [pList],EAX                                                             ; pList - там все ID процессов будут лежать
  invoke EnumProcesses,EAX,1024*4,pCount                                         ; Знать все про процессы хочу!
  invoke ExitProcess,0                                                           ; На выход!

section '.data' data readable writeable
  needed    dd ?
  num       dd ?
  svcHandle dd ?
  svcList   dd ?
  pCount    dd ?
  pList     dd ?

section '.idata' import data readable
  library kernel32,'KERNEL32.DLL',\
          advapi32,'ADVAPI32.DLL',\
          psapi,'PSAPI.DLL'

  import kernel32,\
           ExitProcess,'ExitProcess',\
           VirtualAlloc,'VirtualAlloc'

  import advapi32,\
           EnumServicesStatusEx,'EnumServicesStatusExA',\
           OpenSCManager,'OpenSCManagerA'

  import psapi,\
           EnumProcesses,'EnumProcesses'

 

Короче, все просто! В одной переменной - ссылка на массив указателей на ENUM_SERVICE_STATUS_PROCESS, в каждой лежит SERVICE_STATUS_PROCESS, а в ней - PID. В другой переменной - массив PID-ов всех процессов. Что делать дальше - думаю, все понятно. Разобраться в коде - запросто, там куча комментов, а все функции взяты тупо из MSDN.

 

PS: В зависимости от состояния левой пятки винды, функция EnumProcesses может находиться как в psapi.dll, так и в kernel32.dll - я предупредил!

 

Я сделяль!

ya-sdelyal_96626635_orig_.png

  • Плюс 1
Ссылка на комментарий
Поделиться на другие сайты

lulz:

Скрытый текст

#include "windows.h"
#include "wchar.h"
#include "tlhelp32.h"


LRESULT CALLBACK WndProc(HWND hWnd,UINT uMsg,WPARAM wParam,LPARAM lParam){
static HWND hProcessList;
HFONT hFont;
WCHAR Buffer[300];
PROCESSENTRY32 ProcessEntry;
HANDLE hSnapshot;
SC_HANDLE hSCManager;
DWORD BytesNeeded;
DWORD ServicesReturned;
PBYTE lpServices;
BYTE IsService;

switch (uMsg){
case WM_CREATE:
hFont = CreateFontW(15,6,0,0,FW_MEDIUM,0,0,0,DEFAULT_CHARSET,0,0,PROOF_QUALITY,DEFAULT_PITCH,L"Tahoma");
hProcessList = CreateWindowExW(WS_EX_CLIENTEDGE,L"LISTBOX",0,WS_VISIBLE+WS_CHILD+WS_VSCROLL+LBS_NOTIFY,4,4,276,200,hWnd,(HMENU)1,0,0);
SendMessageW(hProcessList,WM_SETFONT,(WPARAM)hFont,1);
ProcessEntry.dwSize = sizeof(PROCESSENTRY32);
hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS,0);
hSCManager = OpenSCManager(0,SERVICES_ACTIVE_DATABASE,SC_MANAGER_CONNECT+SC_MANAGER_ENUMERATE_SERVICE);
EnumServicesStatusEx(hSCManager,SC_ENUM_PROCESS_INFO,SERVICE_WIN32,SERVICE_STATE_ALL,0,0,&BytesNeeded,&ServicesReturned,0,0);
lpServices = (PBYTE)malloc(BytesNeeded);
EnumServicesStatusEx(hSCManager,SC_ENUM_PROCESS_INFO,SERVICE_WIN32,SERVICE_STATE_ALL,lpServices,BytesNeeded,&BytesNeeded,&ServicesReturned,0,0);
while (Process32NextW(hSnapshot,&ProcessEntry)){
ENUM_SERVICE_STATUS_PROCESS* serv = (ENUM_SERVICE_STATUS_PROCESS*)lpServices;
IsService = 0;
for (DWORD i = 0; i < ServicesReturned; i++){
if (ProcessEntry.th32ProcessID == serv[i].ServiceStatusProcess.dwProcessId){
IsService = 1;
break;
}}
if (!IsService){
swprintf(Buffer,L"Id: %d %s",ProcessEntry.th32ProcessID,ProcessEntry.szExeFile);
SendMessageW(hProcessList,LB_ADDSTRING,0,(LPARAM)Buffer);
}}
free(lpServices);
CloseHandle(hSnapshot);
CloseServiceHandle(hSCManager);
break;

case WM_COMMAND:
if (LOWORD(wParam) == 1){
if (HIWORD(wParam) == LBN_SELCHANGE){
SendMessageW(hProcessList,LB_GETTEXT,SendMessageW(hProcessList,LB_GETCURSEL,0,0),(LPARAM)Buffer);
MessageBoxW(hWnd,Buffer,L"",MB_OK);

DWORD Id = _wtoi(Buffer+4); //skip "Id: "
}}
break;

case WM_GETMINMAXINFO:
MINMAXINFO *lpMinMaxInfo;
lpMinMaxInfo = (MINMAXINFO*)lParam;
lpMinMaxInfo->ptMinTrackSize.x = 300;
lpMinMaxInfo->ptMinTrackSize.y = 250;
break;

case WM_LBUTTONDOWN:
PostMessageW(hWnd,WM_NCLBUTTONDOWN,MK_RBUTTON,0);
break;

case WM_DESTROY:
PostQuitMessage(0);
break;

default:
return DefWindowProcW(hWnd,uMsg,wParam,lParam);
}
return 0;
}


void wmain(){
WNDCLASSEX wcx;
MSG msg;
wcx.cbSize = sizeof(WNDCLASSEX);
wcx.style = 0;
wcx.lpfnWndProc = WndProc;
wcx.cbClsExtra = 0;
wcx.cbWndExtra = 0;
wcx.hInstance = 0;
wcx.hIcon = 0;
wcx.hCursor = LoadCursorW(0,IDC_ARROW);
wcx.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
wcx.lpszMenuName = 0;
wcx.lpszClassName = L"test window";
wcx.hIconSm = 0;
RegisterClassExW(&wcx);
ShowWindow(CreateWindowExW(0,L"test window",L"test window",WS_SYSMENU+WS_MINIMIZEBOX,CW_USEDEFAULT,CW_USEDEFAULT,0,0,0,0,0,0),SW_SHOW);
while (GetMessageW(&msg,0,0,0)){TranslateMessage(&msg);DispatchMessageW(&msg);}
ExitProcess(msg.wParam);
}

кст зачем такое нужно? :D

 

Изменено пользователем Xipho
Не забывай убирать большие куски кода под спойлер!
Ссылка на комментарий
Поделиться на другие сайты

Ну типа , мне нужен только список процессов , как в диспетчере задач .
А у меня выводит ещё и службы (
 

Скрытый текст

 

 

Ссылка на комментарий
Поделиться на другие сайты

×
×
  • Создать...

Важная информация

Находясь на нашем сайте, Вы автоматически соглашаетесь соблюдать наши Условия использования.