Здравствуйте, товарищи программисты! Пишу программу, которая должна вывести список всех процессов компьютера, путей до их Exe, определить владельца процесса.
Снова столкнулся с двумя сложностями, которые не могу решить.
1) Я написал код, который сразу все результаты выводит в консоль. А это оказалось неудобно (((((( Подскажите, пожалуйста, как можно улучшить код, чтобы все собиралось сначала в массив (процесс, путь, владелец), а лишь только затем выводилось на экран? Всю ночь сидел - не смог осилить ((
2) Заметил, что существует процесс audiodg.exe к которому моя программа не находит его путь до exe, хотя он есть... Это такой процесс волшебный или я где-то накосячил?
Подскажите, пожалуйста, что можно еще улучшить/оптимизировать.
Мой код:
PHP код:
#include "stdafx.h"
#include <iostream>
#include <windows.h>
#include <tlhelp32.h>
#include <stdio.h>
#include <tchar.h>
#include <psapi.h>
using namespace std;
#pragma comment(lib, "psapi")
void GetProcessUserName(DWORD dwPID)
{
HANDLE hProcessToken;
HANDLE hProcess;
hProcess=::OpenProcess(PROCESS_QUERY_INFORMATION|PROCESS_VM_READ,0,dwPID);
if(hProcess)
{
if(::OpenProcessToken(hProcess,TOKEN_READ,&hProcessToken))
{
DWORD TokenInformationLength;
DWORD ReturnLength;
PTOKEN_USER tuUser=new TOKEN_USER;
TCHAR UserName[MAX_PATH];
DWORD cchName;
LPWSTR lpReferencedDomainName=new WCHAR[255];
DWORD cchReferencedDomainName;
SID_NAME_USE peUse;
TokenInformationLength=sizeof(tuUser);
if(::GetTokenInformation(hProcessToken,TokenUser,tuUser,TokenInformationLength,&ReturnLength))
{
::LookupAccountSid(NULL,tuUser->User.Sid,UserName,&cchName,lpReferencedDomainName,&cchReferencedDomainName,&peUse);
}
else
{
delete tuUser;
tuUser=(PTOKEN_USER)(new BYTE[ReturnLength]);
TokenInformationLength=ReturnLength;
if(::GetTokenInformation(hProcessToken,TokenUser,tuUser,TokenInformationLength,&ReturnLength))
{
::LookupAccountSid(NULL,tuUser->User.Sid,UserName,&cchName,lpReferencedDomainName,&cchReferencedDomainName,&peUse);
}
delete tuUser;
}
delete lpReferencedDomainName;
_tprintf( TEXT("%s\n"),UserName);
}
else
{
cout<<"система"<<endl;
}
}
}
bool SetProcessPrivileges(wchar_t *privileges)
{
HANDLE processToken;
TOKEN_PRIVILEGES tp;
if(!OpenProcessToken(GetCurrentProcess(),TOKEN_ADJUST_PRIVILEGES,&processToken))
return false;
if(!LookupPrivilegeValue(NULL,privileges,&tp.Privileges[0].Luid))
return false;
tp.PrivilegeCount=1;
tp.Privileges[0].Attributes=SE_PRIVILEGE_ENABLED;
AdjustTokenPrivileges(processToken,false,&tp,0,0,0);
if(GetLastError()!=ERROR_SUCCESS)
return false;
return true;
}
void PrintProcessNameAndID( DWORD processID )
{
TCHAR szProcessName[MAX_PATH] = TEXT("<unknown>");
HANDLE hProcess;
hProcess = OpenProcess( PROCESS_QUERY_INFORMATION |PROCESS_VM_READ,FALSE, processID );
if (NULL != hProcess )
{
HMODULE hMod;
DWORD cbNeeded;
if ( EnumProcessModules( hProcess, &hMod, sizeof(hMod), &cbNeeded) )
{
GetModuleFileNameEx( hProcess, hMod, szProcessName, sizeof(szProcessName) );
}
else
return;
}
else
{
cout<<"система"<<endl;
return;
}
_tprintf(TEXT("%s\n"), szProcessName);
CloseHandle( hProcess );
}
int main(void) // по стандарту должна возвращать значение
{
TCHAR UserName[MAX_PATH];
SetProcessPrivileges(SE_DEBUG_NAME);
setlocale(LC_ALL,"rus"); // для вывода русских символов
OSVERSIONINFO osinfo;
osinfo.dwOSVersionInfoSize=sizeof(OSVERSIONINFO);
if (!GetVersionEx(&osinfo))
{
printf("Unable to get OS version!\n");
return 1;
}
if (osinfo.dwPlatformId & VER_PLATFORM_WIN32_NT)
{
if (osinfo.dwMajorVersion<5)
{
printf("ToolHelp API isn't support on NT versions prior to Windows 2000!\n");
return 1;
}
}
HANDLE hSnapshot=CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS,0);
if (!hSnapshot)
{
printf("Unable to create snapshot!\n");
return 1;
}
PROCESSENTRY32 pe;
ULONG count=0;
pe.dwSize=sizeof(PROCESSENTRY32);
BOOL retval=Process32First(hSnapshot,&pe);
while(retval)
{
count++;
_tprintf( TEXT("%s\n"),pe.szExeFile);
PrintProcessNameAndID(pe.th32ProcessID);
GetProcessUserName(pe.th32ProcessID);
cout<<endl;
retval=Process32Next(hSnapshot,&pe);
}
CloseHandle(hSnapshot);
printf("%lu processes enumerated\n",count);
system("pause"); // ждать нажатия клавиши
// return 0; - можно не писать, по стандарту main вернет 0
}