How can I get a process handle by its name in C++?

C++WinapiProcess

C++ Problem Overview


I'm trying to get the process handle of, say example.exe, so I can call TerminateProcess on it. How can I do this? Notice, it doesn't have a window so FindWindow won't work.

C++ Solutions


Solution 1 - 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;
}

Solution 2 - C++

The following code shows how you can use toolhelp and OpenProcess to get a handle to the process. Error handling removed for brevity.

HANDLE GetProcessByName(PCSTR name)
{
    DWORD pid = 0;

    // Create toolhelp snapshot.
    HANDLE snapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
    PROCESSENTRY32 process;
    ZeroMemory(&process, sizeof(process));
    process.dwSize = sizeof(process);

    // Walkthrough all processes.
    if (Process32First(snapshot, &process))
    {
        do
        {
            // Compare process.szExeFile based on format of name, i.e., trim file path
            // trim .exe if necessary, etc.
            if (string(process.szExeFile) == string(name))
            {
               pid = process.th32ProcessID;
               break;
            }
        } while (Process32Next(snapshot, &process));
    }

    CloseHandle(snapshot);

    if (pid != 0)
    {
         return OpenProcess(PROCESS_ALL_ACCESS, FALSE, pid);
    }

    // Not found


       return NULL;
}

Solution 3 - C++

There are two basic techniques. The first uses PSAPI; MSDN has an example that uses EnumProcesses, OpenProcess, EnumProcessModules, and GetModuleBaseName.

The other uses Toolhelp, which I prefer. Use CreateToolhelp32Snapshot to get a snapshot of the process list, walk over it with Process32First and Process32Next, which provides module name and process ID, until you find the one you want, and then call OpenProcess to get a handle.

Solution 4 - C++

The following code can be used:

DWORD FindProcessId(const std::wstring& processName)
{
	PROCESSENTRY32 processInfo;
	processInfo.dwSize = sizeof(processInfo);

	HANDLE processesSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, NULL);
	if (processesSnapshot == INVALID_HANDLE_VALUE) {
		return 0;
	}

	Process32First(processesSnapshot, &processInfo);
	if (!processName.compare(processInfo.szExeFile))
	{
		CloseHandle(processesSnapshot);
		return processInfo.th32ProcessID;
	}

	while (Process32Next(processesSnapshot, &processInfo))
	{
		if (!processName.compare(processInfo.szExeFile))
		{
			CloseHandle(processesSnapshot);
			return processInfo.th32ProcessID;
		}
	}

	CloseHandle(processesSnapshot);
	return 0;
}

Usage:

auto processId = FindProcessId(L"blabla.exe");

Getting a handle should be obvious, just call OpenProcess() or similar on it.

Solution 5 - C++

Check out: http://msdn.microsoft.com/en-us/library/ms682489(VS.85).aspx">MSDN Article

You can use GetModuleName (I think?) to get the name and check against that.

Solution 6 - C++

OpenProcess Function

From MSDN:

To open a handle to another local process and obtain full access rights, you must enable the SeDebugPrivilege privilege.

Solution 7 - C++

If you don't mind using system(), doing system("taskkill /f /im process.exe") would be significantly easier than these other methods.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionMalfistView Question on Stackoverflow
Solution 1 - C++xianView Answer on Stackoverflow
Solution 2 - C++MichaelView Answer on Stackoverflow
Solution 3 - C++Rob KennedyView Answer on Stackoverflow
Solution 4 - C++BullyWiiPlazaView Answer on Stackoverflow
Solution 5 - C++LloydView Answer on Stackoverflow
Solution 6 - C++aJ.View Answer on Stackoverflow
Solution 7 - C++user13690398View Answer on Stackoverflow