I'm recently looking to list every processes of a machine to do some action. But I'm struggling with processes which are not launched from my user (eg: system, administrator or an other user).
I tried some codes and some solutions but there is still anything who works.
I am working on the code proposed by microsoft to enumerate all the processes.
Here is the code :
#include <windows.h>
#include <stdio.h>
#include <tchar.h>
#include <psapi.h>
// To ensure correct resolution of symbols, add Psapi.lib to TARGETLIBS
// and compile with -DPSAPI_VERSION=1
void PrintProcessNameAndID( DWORD processID )
{
TCHAR szProcessName[MAX_PATH] = TEXT("<unknown>");
// Get a handle to the process.
HANDLE hProcess = OpenProcess( PROCESS_QUERY_INFORMATION |
PROCESS_VM_READ,
FALSE, processID );
// Get the process name.
if (NULL != hProcess )
{
HMODULE hMod;
DWORD cbNeeded;
if ( EnumProcessModules( hProcess, &hMod, sizeof(hMod),
&cbNeeded) )
{
GetModuleBaseName( hProcess, hMod, szProcessName,
sizeof(szProcessName)/sizeof(TCHAR) );
}
}
// Print the process name and identifier.
_tprintf( TEXT("%s (PID: %u)\n"), szProcessName, processID );
// Release the handle to the process.
CloseHandle( hProcess );
}
int main( void )
{
// Get the list of process identifiers.
DWORD aProcesses[1024], cbNeeded, cProcesses;
unsigned int i;
if ( !EnumProcesses( aProcesses, sizeof(aProcesses), &cbNeeded ) )
{
return 1;
}
// Calculate how many process identifiers were returned.
cProcesses = cbNeeded / sizeof(DWORD);
// Print the name and process identifier for each process.
for ( i = 0; i < cProcesses; i )
{
if( aProcesses[i] != 0 )
{
PrintProcessNameAndID( aProcesses[i] );
}
}
return 0;
}
This code works but does not allow you to view the processes of other users. Do you have an idea?
Thanks everyone for your time. Regards
CodePudding user response:
The most reasonable solution I think would be to use CreateToolhelp32Snapshot You can do some looking up on it at https://docs.microsoft.com/en-us/windows/win32/api/tlhelp32/nf-tlhelp32-createtoolhelp32snapshot
Heres a small example
HANDLE hProcessSnap;
PROCESSENTRY32 pe32;
hProcessSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
if (hProcessSnap == INVALID_HANDLE_VALUE)
{
std::cout << "CreateToolhelp32Snapshot (of processes) failed with error " << GetLastError() << std::endl;
return;
pe32.dwSize = sizeof(PROCESSENTRY32);
if (!Process32First(hProcessSnap, &pe32))
{
std::cout << "Failed getting first process" << std::endl;
CloseHandle(hProcessSnap);
return;
}
do
{
std::cout << "Process: " << pe32.szExeFile << std::endl;
} while (Process32Next(hProcessSnap, &pe32));
CloseHandle(hProcessSnap);
CodePudding user response:
As a normal user, you are not going to get far by using OpenProcess
on processes you don't own. If you elevate your process and enable the debug privilege you might have more luck. You will probably still be denied access to DRM and AntiVirus processes. In general the PSAPI functions expect a lot of access to the process with PROCESS_VM_READ
being the biggest issue, Windows is not going to grant you memory read access to all other processes. Some of the newer APIs like GetProcessImageFileName
have been upgraded (in Vista ) to only require PROCESS_QUERY_LIMITED_INFORMATION
which you might be able to get for more processes.
I would suggest using the Toolhelp API instead, it should provide a little more info than EnumProcesses
OpenProcess
. You can also get some information from the Performance Counters and WMI.
As a side note; EnumProcesses
is the most useless API ever. It uses the NT API to get information about all processes then throws away all that information except the process ids.
If you are willing to use undocumented stuff, the NT Query/Information functions will give you more information than any documented API.