How can I get a process handle by its name in C++?
#include <cstdio>
#include <windows.h>
#include <tlhelp32.h>
int main( int, char *[] )
{
PROCESSENTRY32 entry;
entry.dwSize = sizeof(PROCESSENTRY32);
HANDLE snapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, NULL);
if (Process32First(snapshot, &entry) == TRUE)
{
while (Process32Next(snapshot, &entry) == TRUE)
{
if (stricmp(entry.szExeFile, "target.exe") == 0)
{
HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, entry.th32ProcessID);
// Do stuff..
CloseHandle(hProcess);
}
}
}
CloseHandle(snapshot);
return 0;
}
Also, if you'd like to use PROCESS_ALL_ACCESS in OpenProcess, you could try this:
#include <cstdio>
#include <windows.h>
#include <tlhelp32.h>
void EnableDebugPriv()
{
HANDLE hToken;
LUID luid;
TOKEN_PRIVILEGES tkp;
OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hToken);
LookupPrivilegeValue(NULL, SE_DEBUG_NAME, &luid);
tkp.PrivilegeCount = 1;
tkp.Privileges[0].Luid = luid;
tkp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
AdjustTokenPrivileges(hToken, false, &tkp, sizeof(tkp), NULL, NULL);
CloseHandle(hToken);
}
int main( int, char *[] )
{
EnableDebugPriv();
PROCESSENTRY32 entry;
entry.dwSize = sizeof(PROCESSENTRY32);
HANDLE snapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, NULL);
if (Process32First(snapshot, &entry) == TRUE)
{
while (Process32Next(snapshot, &entry) == TRUE)
{
if (stricmp(entry.szExeFile, "target.exe") == 0)
{
HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, entry.th32ProcessID);
// Do stuff..
CloseHandle(hProcess);
}
}
}
CloseHandle(snapshot);
return 0;
}
How to get the process name based on hwnd in C
The return value of GetWindowThreadProcessId()
is a thread ID, not a process ID, so DO NOT assign that return value to your process_ID
variable, or else it will overwrite the value that was output by the lpdwProcessId
parameter.
HWND hwnd = GetForegroundWindow();
DWORD process_ID = 0;
if (GetWindowThreadProcessId(hwnd, &process_ID))
{
// get the process name ...
}
else
{
// error handling ...
}
Once you have the process ID, you can pass it to OpenProcess()
to get a HANDLE
to the running process, and then use that HANDLE
with either GetModuleFileNameEx()
, GetProcessImageFileName()
(XP+), or QueryFullProcessImageName()
(Vista+) to get the full path and filename of that process's EXE file:
HANDLE hProcess = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, process_ID);
if (hProcess)
{
WCHAR process_name[MAX_PATH] = {};
if (GetModuleFileNameExW(hProcess, NULL, process_name, MAX_PATH))
{
// use process_name as needed...
}
else
{
// error handling ...
}
CloseHandle(hProcess);
}
else
{
// error handling ...
}
HANDLE hProcess = OpenProcess(PROCESS_QUERY_LIMITED_INFORMATION, FALSE, process_ID);
if (hProcess)
{
WCHAR process_name[MAX_PATH] = {};
if (GetProcessImageFileNameW(hProcess, process_name, MAX_PATH))
{
// use process_name as needed...
}
else
{
// error handling ...
}
CloseHandle(hProcess);
}
else
{
// error handling ...
}
HANDLE hProcess = OpenProcess(PROCESS_QUERY_LIMITED_INFORMATION, FALSE, process_ID);
if (hProcess)
{
WCHAR process_name[MAX_PATH] = {};
DWORD size = MAX_PATH;
if (QueryFullProcessImageNameW(hProcess, 0, process_name, &size))
{
// use process_name as needed...
}
else
{
// error handling ...
}
CloseHandle(hProcess);
}
else
{
// error handling ...
}
Get the process handle of a process by image name
Use CreateToolhelp32Snapshot, Process32First, and Process32Next to enumerate all of the processes.
Inside the PROCESSENTRY32 you can find a szExeFile
member.
You can get the process handle by calling OpenProcess with the process ID th32ProcessID
within the same struct.
Once you find a process matching your exe name, you can break out of your loop and obtain the handle.
Note: If you need to enumerate EVERY process no matter what the session is, you should acquire the SE_DEBUG privilege.
At the top of your main call this:
acquirePrivilegeByName(SE_DEBUG_NAME);// SeDebugPrivilege
And here is the definition of acquirePrivilegeByName
:
BOOL acquirePrivilegeByName(
const TCHAR *szPrivilegeName)
{
HANDLE htoken;
TOKEN_PRIVILEGES tkp;
DWORD dwerr;
if (szPrivilegeName == NULL)
{
SetLastError(ERROR_INVALID_PARAMETER);
return FALSE;
}
if (!LookupPrivilegeValue(NULL, szPrivilegeName, &(tkp.Privileges[0].Luid)))
return FALSE;
tkp.PrivilegeCount = 1;
tkp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
if (!OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES, &htoken))
return FALSE;
if (!AdjustTokenPrivileges(htoken, FALSE, &tkp, 0, NULL, NULL) ||
GetLastError() != ERROR_SUCCESS) // may equal ERROR_NOT_ALL_ASSIGNED
{
dwerr = GetLastError();
CloseHandle(htoken);
SetLastError(dwerr);
return FALSE;
}
CloseHandle(htoken);
SetLastError(ERROR_SUCCESS);
return TRUE;
} //acquirePrivilegeByName()
In addition to what I said above, there is an example on how to use the above Win32 API here.
How can I get a process handle not by its name in C?
You can do this with the following sequence of Win32 API calls:
- Use Spy++ or something similar to find the class name of the top level window you are targeting.
- Call
FindWindow
orEnumWindows
to find top-level windows with that class name. - Call
GetWindowThreadProcessId
to find the process ID of each window of interest. - Call
OpenProcess
passing the process ID to get a process handle.
getting process handle name
You allocate memory for the nameInfo
variable, but do not initialize it. So when you try to use it, nameInfo->Buffer
contains 0xBAADF00D
- Microsoft magic number for uninitialized heap memory. Then you get access violation. You also should use WideCharToMultibyte
function for string conversion.
get a process id from process name
Because there might be several instances of a process name running, there is no one-to-one correlation between a process's image name and a PID. You'll have to enumerate the processes and check the base module names for each one as Burgos describes, by using EnumProcesses.
FWIW, .Net approaches this problem by providing the GetProcessesByName API, which returns a collection of process objects. Not much use to you of course :-(
How to get Process name from process id in windows through C++ without enumerating process?
I need to get process name from process id in windows to find process names associated with a logged event.
If you are getting the Process ID from a log, it will only be valid if the original process is still running. Otherwise, the ID is no longer valid for that process name. If the process has already exited before you read the log, all bets are off.
I need not currently running process since it talks about logged event.
Then you are out of luck, if the original process name was not logged.
I have a doubt of whether processID vs processName combination is unique or not in Windows.
A Process ID is unique only while being used for a running process. Once a process ends, its Process ID is no longer valid, and can be re-used for a subsequent new process.
I expect that there must be some structure to map process id to process name.
Yes, but only for a running process. You can pass the Process ID to OpenProcess()
. If successful, it will return a HANDLE
to the running process. You can then pass that HANDLE
to GetModuleFileName()
, GetProcessImageFileName()
, or QueryFullProcessImageName()
, depending on OS version and permissions you are able to gain from OpenProcess()
.
How to give a program's Handle to a process it created?
The easiest way to transmit this handle seems to be by putting the Handle in the commandline arguments of
CreateProcess
That is one way to do it, but it is not the only way.
Another simple way is to have Parent
send its process ID from GetCurrentProcessId()
to Kid
, and then Kid
can use OpenProcess()
to get a handle to Parent
.
there is no way I can see to get the Parent's Handle inside Parent.
GetCurrentProcess()
, which returns a pseudo-handle representing the calling process. All APIs that accept a process handle will accept this pseudo-handle when used in the context of the calling process.
But, for purposes of passing the calling process's handle to another process, Parent
would have to use DuplicateHandle()
to convert the pseudo-handle into a real handle (set Parent
as both source and target process). This is documented behavior.
GetCurrentProcess
returns a weird non-value, andDuplicateHandle
doesn't work without having the Kid's Handle
After Parent
has duplicated the pseudo-handle from GetProcessHandle()
into a real handle, it can then pass that duplicate to Kid
on the command line. Just make sure the duplicate is inheritable, and then use bInheritHandles=TRUE
in the CreateProcess()
call, or pass a STARTUPINFOEX
to CreateProcess()
containing a PROC_THREAD_ATTRIBUTE_HANDLE_LIST
(see Programmatically controlling which handles are inherited by new processes in Win32).
Impossible, since I need to create the Kid to get a Handle to it
If you don't want to use inheritable handles, then Parent
can alternatively create Kid
without passing any handle on the command line, then duplicate the GetCurrentProcess()
pseudo-handle with Kid
as the target process, then use an IPC mechanism of your choosing to send the duplicate to Kid
after it is already running.
but
CreateProcess
is also the only chance to send the Parent's Handle to the Kid
No, it is not the only way. IPC is another way.
Related Topics
What Are the Rules For Automatic Generation of Move Operations
Standard Library Sort and User Defined Types
C++ Get Name of Type in Template
What Made I = I++ + 1; Legal in C++17
Msvc++ Variadic Macro Expansion
What Does Std::Match_Results::Size Return
Why Can't Clang With Libc++ in C++0X Mode Link This Boost::Program_Options Example
C++ [] Array Operator With Multiple Arguments
Advantages of Using Std::Make_Unique Over New Operator
How to Printf Uint64_T? Fails With: "Spurious Trailing '%' in Format"
When Passing an Array to a Function in C++, Why Won't Sizeof() Work the Same as in the Main Function
How to Get a Process Handle by Its Name in C++
Trailing Return Type Using Decltype With a Variadic Template Function
How to Get Iostream to Perform Better