I'm using the EnumProcesses function to get all process IDs on the system. Then I iterate over each process ID and pass it to OpenProcess to get a process handle, which I then pass to GetProcessImageFileNameA to get the process name.
Here's a code snippet:
#include <stdio.h>
#include <tchar.h>
#include <Windows.h>
#include <Psapi.h>
DWORD GetProcessName(DWORD processID, TCHAR lpFileName, DWORD nSize)
{
HANDLE hProcess;
DWORD pLength;
// Get process handle
hProcess = OpenProcess(
PROCESS_VM_READ | PROCESS_QUERY_INFORMATION,
FALSE,
processID
);
if ( !hProcess )
return NULL;
// Write process name to buffer
if ( pLength = GetProcessImageFileNameA(hProcess, lpFileName, nSize) )
{
CloseHandle(hProcess);
return pLength;
}
CloseHandle(hProcess);
}
int main(void)
{
DWORD processIDs[PROC_ID_SIZE], cbNeeded, cProcess;
unsigned int i;
// Get process IDs
if ( !EnumProcesses(processIDs, sizeof(processIDs), &cbNeeded) )
return 1;
// Get process ID count
cProcess = cbNeeded / sizeof(DWORD);
printf("Number of Processes: %u | Size of Process Array: %d\n", cProcess, (int)sizeof(processIDs));
// Get the process name of each process
for (i = 0; i < cProcess; i++)
{
if ( processIDs[i] != 0 )
{
// The access violation is happening here
TCHAR processName[MAX_PATH];
GetProcessName(processIDs[i], processName, sizeof(processName));
printf("Process name: %s\n", (char*)processName);
}
}
return 0;
}
It compiles fine, but I get this runtime error:
Exception thrown at 0x00007FF985433338 (KernelBase.dll) in QuickSave.exe: 0xC0000005: Access violation writing location 0x000000000000F8D0.
I have a suspicion it's because I'm declaring processName from outside of the function's scope. When I create another function and declare processName within that function's scope, it works. I'm not entirely sure why.
DWORD PrintProcessName(DWORD processID)
{
HANDLE hProcess;
TCHAR processName[MAX_PATH];
DWORD pLength;
// Get process handle
hProcess = OpenProcess(
PROCESS_VM_READ | PROCESS_QUERY_INFORMATION,
FALSE,
processID
);
if (!hProcess)
return NULL;
// Write process name to buffer and print it
if ( pLength = GetProcessImageFileNameA(hProcess, processName, sizeof(processName)) )
{
printf("Process name: %s\n", (char*)processName);
return pLength;
}
CloseHandle(hProcess);
}
I'm still learning C so I'm probably making a newbie mistake, but hopefully someone can help me make sense of what's going on here.
I have fixed your code. The main errors was bad declaration of GetProcessName, wrong size passed for processName size, incorrect printf format specification, function doesn't always return a value, missing error checks.
#include <stdio.h>
#include <tchar.h>
#include <Windows.h>
#include <Psapi.h>
#define PROC_ID_SIZE 1000
DWORD GetProcessName(DWORD processID, TCHAR *lpFileName, DWORD nSize)
{
HANDLE hProcess;
DWORD pLength;
// Get process handle
hProcess = OpenProcess(
PROCESS_QUERY_LIMITED_INFORMATION,
FALSE,
processID
);
if (!hProcess)
return 0;
// Write process name to buffer
pLength = GetProcessImageFileNameW(hProcess, lpFileName, nSize);
CloseHandle(hProcess);
return pLength;
}
int main(void)
{
DWORD processIDs[PROC_ID_SIZE], cbNeeded, cProcess;
unsigned int i;
// Get process IDs
if (!EnumProcesses(processIDs, sizeof(processIDs), &cbNeeded))
return 1;
// Get process ID count
cProcess = cbNeeded / sizeof(DWORD);
printf("Number of Processes: %u | Size of Process Array: %d\n", cProcess, (int)sizeof(processIDs));
// Get the process name of each process
for (i = 0; i < cProcess; i++)
{
if (processIDs[i] != 0)
{
// The access violation is happening here
TCHAR processName[MAX_PATH];
if (GetProcessName(processIDs[i], processName, sizeof(processName)/sizeof(processName[0])))
printf("Process name: %ls\n", processName);
}
}
return 0;
}
Related
I'm curious if there are methods to run code after the main() program has closed?
So far, I've found atexit()
int atexit( void (*func)(void) );
Registers the function pointed to by func to be called on normal
program termination (via exit() or returning from main()). The
functions will be called in reverse order they were registered, i.e.
the function registered last will be executed first.
For example, Chrome browser with pid 358440 calls the injected atexit(). Closing the browser normally launches the Windows calculator. Perhaps there are less intrusive ways?
Bunny.c
// Windows x86-64: Create a remote thread to run atexit().
// Configuration: MSVC 2019 Debug x64.
#include <Windows.h>
#include <stdio.h>
#include <stdint.h>
#include <intrin.h>
typedef uint64_t QWORD;
typedef void (*funcPtr)(void);
typedef void (*AtexitPtr)(funcPtr);
// ------------------------------------------------------------
#define kExitFunctionAddress_offset 16
#define kWinExecAddress_offset 30
#define kAtExitAddress_offset 44
#define kRunAtexit_offset 58
// ------------------------------------------------------------
DWORD WINAPI start_of_function_code(void)
{
// ------------------------------------------------------------
QWORD kExitFunctionAddress = 0xDEADBEEFBAADF00D;
QWORD kWinExecAddress = 0xDEADBEEFBAADF00D;
QWORD kAtExitAddress = 0xDEADBEEFBAADF00D;
QWORD kRunAtexit = 0xDEADBEEFBAADF00D;
// ------------------------------------------------------------
if (kRunAtexit)
{
AtexitPtr atexit_ptr = (AtexitPtr)kAtExitAddress;
atexit_ptr((funcPtr)kExitFunctionAddress);
}
else
{
const char kCalculator[] = { 'c','a','l','c','.','e','x','e','\0' };
((FARPROC(WINAPI*)(LPCSTR, UINT))(kWinExecAddress))(kCalculator, SW_SHOW);
}
return 0;
}
int main(int argc, char* argv[])
{
DWORD targetPID;
HANDLE hTargetProc;
LPTHREAD_START_ROUTINE pfnThreadRoutine;
HANDLE hRemoteThread;
DWORD sizeoffunccode;
QWORD onoff = 0;
BYTE RETURN_OPCODE = 0xC3;
// Get the target PID
if (argc < 2) {
printf("Usage: %s <target PID>\n", argv[0]);
return 1;
}
targetPID = atoi(argv[1]);
HANDLE hProcess = OpenProcess(PROCESS_QUERY_INFORMATION, FALSE, targetPID);
if (hProcess == NULL)
{
printf("[+] Invalid PID %d\n", targetPID);
exit(1);
}
CloseHandle(hProcess);
// Get Function Code Size
BYTE* end_of_function_code = (BYTE*)start_of_function_code;
while (*end_of_function_code++ != RETURN_OPCODE) {};
sizeoffunccode = (DWORD)(end_of_function_code - (BYTE*)start_of_function_code);
printf("[+] Function Size %d bytes\n", sizeoffunccode);
// Get function addresses for Winexec() and atexit()
HMODULE kernel32 = LoadLibrary("Kernel32.dll");
FARPROC winexec = GetProcAddress(kernel32, "WinExec");
printf("[+] Winexec() Address %p\n", winexec);
HMODULE msvcrt = LoadLibrary("msvcrt.dll");
FARPROC atexit = GetProcAddress(msvcrt, "atexit");
printf("[+] atexit() Address %p\n", atexit);
// Write the thread function to the target process
hTargetProc = OpenProcess(PROCESS_ALL_ACCESS, FALSE, targetPID);
pfnThreadRoutine = (LPTHREAD_START_ROUTINE)VirtualAllocEx(hTargetProc, NULL, sizeoffunccode, MEM_COMMIT, PAGE_EXECUTE_READWRITE);
WriteProcessMemory(hTargetProc, pfnThreadRoutine, (BYTE*)start_of_function_code, sizeoffunccode, NULL);
WriteProcessMemory(hTargetProc, (BYTE*)pfnThreadRoutine + kExitFunctionAddress_offset, &pfnThreadRoutine, sizeof(pfnThreadRoutine), NULL);
WriteProcessMemory(hTargetProc, (BYTE*)pfnThreadRoutine + kWinExecAddress_offset, &winexec, sizeof(winexec), NULL);
WriteProcessMemory(hTargetProc, (BYTE*)pfnThreadRoutine + kAtExitAddress_offset, &atexit, sizeof(atexit), NULL);
printf("[+] Function Address %p (PID: %d)\n", pfnThreadRoutine, targetPID);
// Create the remote thread and call atexit()
hRemoteThread = CreateRemoteThread(hTargetProc, NULL, 0, pfnThreadRoutine, NULL, 0, NULL);
WaitForSingleObject(hRemoteThread, INFINITE);
printf("[+] atexit() Executed\n");
// Toggle condition so WinExec() is called upon process exit
WriteProcessMemory(hTargetProc, (BYTE*)pfnThreadRoutine + kRunAtexit_offset, &onoff, sizeof(onoff), NULL);
printf("[+] WinExec() Primed\n");
// Cleanup
CloseHandle(hTargetProc);
CloseHandle(hRemoteThread);
printf("[+] Done.\n");
return 0;
}
I'm trying to get handles of windows. Then I was trying to get associated process id for every handle. But somehow, I'm magically get process_id out of nowhere. Please guide me here.
If I try to initialize process_id using GetWindowThreadProcessId() function, I encounter a runtime error.
However, if I comment out that part of code and let process_id print in both printf() functions, the programs runs successfully, displays data and exits cleanly. It should be garbage value here.
#include <stdio.h>
#include <windows.h>
WNDENUMPROC DisplayData(HWND str, LPARAM p) {
LPDWORD process_id;
DWORD P_ID;
printf("PID :: %x\n", process_id);
//this is where error occurs
//P_ID = GetWindowThreadProcessId(str, process_id);
printf("Found: %x, P_ID: %x\n", str, process_id);
return TRUE;
}
int main() {
EnumWindows( (WNDENUMPROC) DisplayData, 1);
return 0;
}
#include <stdio.h>
#include <windows.h>
LPDWORD target = (LPDWORD) 0; // Replace 0 with PID of the task from taskmgr.
HWND target_handle = NULL; // stores the handle of the target process
WNDENUMPROC DisplayData(HWND str, LPARAM p) {
LPDWORD thread_id;
DWORD process_id;
char title[30];
GetWindowTextA(str, (LPSTR) &title, 29);
process_id = GetWindowThreadProcessId(str, (PDWORD) &thread_id);
if( thread_id == target & IsWindowVisible(str) ) {
// Target thread with associated handle
// printf("Handle Addr: %lu, Thread ID: %lu, Process ID: %lu, Title: %s\n", str, thread_id, process_id, title );
target_handle = str;
}
return TRUE;
}
int main() {
EnumWindows( (WNDENUMPROC) DisplayData, 1);
ShowWindow(target_handle, SW_HIDE);
Sleep(1000);
ShowWindow(target_handle, SW_SHOW);
return 0;
}
The Thread ID shown by this code is the one that is displayed in Task Manager as PID. target_handle variable contains handle address after the execution of EnumWindows() function, just as required.
I'm new to Win32 programming.
I'm trying to pass a HANDLE obtained using CreateFile() to a function in a DLL.
But upon trying to read bytes, dwBytesRead says 0.
Am I allowed to pass HANDLEs to DLL entries? I read here [Writing DLLs] that resources of the caller do not belong to callee, and hence I should not call CloseHandle() or things like free() for malloc() in caller.
Is my understanding correct? Kindly point me in the right direction. Here's the code:
main.c
#include <windows.h>
#include <tchar.h>
#include <stdio.h>
#include <strsafe.h>
#define BUFFERSIZE 5
int __declspec( dllimport ) hello( HANDLE );
void __cdecl _tmain(int argc, TCHAR *argv[])
{
HANDLE hFile;
printf("\n");
if( argc != 2 )
{
printf("Usage Error: Incorrect number of arguments\n\n");
_tprintf(TEXT("Usage:\n\t%s <text_file_name>\n"), argv[0]);
return;
}
hFile = CreateFile(argv[1], // file to open
GENERIC_READ, // open for reading
FILE_SHARE_READ, // share for reading
NULL, // default security
OPEN_EXISTING, // existing file only
FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED, // normal file
NULL); // no attr. template
if (hFile == INVALID_HANDLE_VALUE)
{
_tprintf(TEXT("Terminal failure: unable to open file \"%s\" for read.\n"), argv[1]);
return;
}
printf( "Entered main, calling DLL.\n" );
hello(hFile);
printf( "Back in main, exiting.\n" );
CloseHandle(hFile);
}
hello.c
#include <windows.h>
#include <tchar.h>
#include <stdio.h>
#include <strsafe.h>
#define BUFFERSIZE 5
DWORD g_BytesTransferred = 0;
VOID CALLBACK FileIOCompletionRoutine(
__in DWORD dwErrorCode,
__in DWORD dwNumberOfBytesTransfered,
__in LPOVERLAPPED lpOverlapped )
{
_tprintf(TEXT("Error code:\t%x\n"), dwErrorCode);
_tprintf(TEXT("Number of bytes:\t%x\n"), dwNumberOfBytesTransfered);
g_BytesTransferred = dwNumberOfBytesTransfered;
}
int __declspec( dllexport ) hello( HANDLE hFile )
{
DWORD dwBytesRead = 0;
char ReadBuffer[BUFFERSIZE] = {0};
OVERLAPPED ol = {0};
if( FALSE == ReadFileEx(hFile, ReadBuffer, BUFFERSIZE-1, &ol, FileIOCompletionRoutine) )
{
DWORD lastError = GetLastError();
printf("Terminal failure: Unable to read from file.\n GetLastError=%08x\n", lastError);
return lastError;
}
dwBytesRead = g_BytesTransferred;
if (dwBytesRead > 0 && dwBytesRead <= BUFFERSIZE-1)
{
ReadBuffer[dwBytesRead]='\0';
printf("Data read from file (%d bytes): \n", dwBytesRead);
printf("%s\n", ReadBuffer);
}
else if (dwBytesRead == 0)
{
printf("No data read from file \n");
}
else
{
printf("\n ** Unexpected value for dwBytesRead ** \n");
}
printf( "Hello from a DLL!\n" );
return( 0 );
}
You are missing the SleepEx(5000, TRUE) call from the example.
You are using async-io, in which case you will receive a callback when the read occurs. If you don't wait for the callback you may get 0 bytes read depending on when the callback is triggered.
I try to get Handle ID of opened applications (windows).
I run Window detective program, (like spy++) to verify that I get proper values.
For testing I try to get only one Handle Id pointed by red arrow (see the image):
So I have program that gives me process id and thread Id but not 1st Child Handle ID.
In my case I took calc.exe, but actually I need to do that for all exe applications:
readWindow.c
#include <windows.h>
#include <stdio.h>
#include <stddef.h>
#include <inttypes.h>
#include <tchar.h>
#include <psapi.h>
HMODULE getModulePid(DWORD processID, char* searchStr){ // gets the module by the module name from an explicit process
HANDLE hProcess;
HMODULE hMods[1024];
TCHAR szModName[MAX_PATH];
DWORD cbNeeded;
if(hProcess = OpenProcess( PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, processID ))
{
if(EnumProcessModules(hProcess, hMods, sizeof(hMods), &cbNeeded))
{
unsigned int k;
for(k = 0; k < (cbNeeded / sizeof(HMODULE)); ++k )
{
if (GetModuleFileNameEx(hProcess, hMods[k], szModName, sizeof(szModName)/sizeof(TCHAR)))
{
//printf( "fess pid: %u modname: %s\n", processID, szModName );
if(strstr(szModName, searchStr))
{
printf( "pid: %u modname: %s\n", processID, szModName );
CloseHandle( hProcess );
return hMods[k];
}
}
}//for
}
}
CloseHandle( hProcess );
return NULL;
}
HMODULE getModule(char* searchStr){ // gets the module by the modul name from all processes
DWORD aProcesses[1024], cbNeeded, cProcesses;
if ( !EnumProcesses( aProcesses, sizeof(aProcesses), &cbNeeded ) ) return NULL;
cProcesses = cbNeeded / sizeof(DWORD);
HMODULE hmodule;
unsigned int i;
for (i = 0; i < cProcesses; ++i )
{
if(hmodule = getModulePid(aProcesses[i], searchStr))
{
return hmodule;
}
}
return NULL;
}
HMODULE getModuleHwnd(HWND hwnd){ // gets the module from a window
DWORD pid;
DWORD tid = GetWindowThreadProcessId(hwnd, &pid ); // !!??!!
printf( "hwnd tid: %u\n", tid );
printf( "hwnd pid: %u\n", pid );
return getModulePid(pid, ".exe");
}
HMODULE hModuleT;
char* searchStrT;
BOOL CALLBACK shownWindow(HWND hwnd, LPARAM lParam){ // EnumWindows callback
if(hModuleT) return TRUE;
char pcWinTitle[256];
if(GetWindow(hwnd, GW_OWNER)) return TRUE; // whats that?
GetWindowText(hwnd, pcWinTitle, 1024);
if(strstr(pcWinTitle, searchStrT)){
printf( "wndtitle: %s\n", pcWinTitle);
hModuleT = getModuleHwnd(hwnd);
}
return TRUE;
}
HMODULE getModuleByWndTitle(char* searchStr){ // gets the module from a window title
searchStrT = searchStr;
EnumWindows(shownWindow, 0);
return hModuleT;
}
int main()
{
//EnumWindows(EnumWindowsProc, 0);
printf("find by name ... \n");
getModule("calc.exe");
printf("\nfind by title ... \n");
getModuleByWndTitle("Calculator");
printf("Done");
return 0;
}
Run from minGW:
$ gcc -L/local/lib -I/local/include -o readWindow readWindow.c -lpsapi
Output:
find by title ...
wndtitle: Calculator
hwnd tid: 33364
hwnd pid: 25440
Done
How can I get the Handle from Process?
I'm sure it should be some 1-2 rows of code.
DWORD dwValue .....
printf("The value in hexa: 0X%.8X(%d).\n", dwValue);
it should be 0x007B137C
From Spy++ I need this value, red arrow:
It was pretty easy but for me tricky a bit.
I just need to print pointer HWND hwnd with %p.
So I added to my code:
char szBuff[512];
sprintf(szBuff, "%p", hwnd);
printf( "Found .... hWnd: %s\n", szBuff);
And got what I need:
Found .... hWnd: 007B137C
[EDIT]
Working code example:
readWindow.c
#include <windows.h>
#include <stdio.h>
#include <stddef.h>
#include <inttypes.h>
#include <tchar.h>
#include <psapi.h>
HMODULE getModulePid(DWORD processID, char* searchStr){ // gets the module by the module name from an explicit process
HANDLE hProcess;
HMODULE hMods[1024];
TCHAR szModName[MAX_PATH];
DWORD cbNeeded;
if(hProcess = OpenProcess( PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, processID ))
{
if(EnumProcessModules(hProcess, hMods, sizeof(hMods), &cbNeeded))
{
unsigned int k;
for(k = 0; k < (cbNeeded / sizeof(HMODULE)); ++k )
{
if (GetModuleFileNameEx(hProcess, hMods[k], szModName, sizeof(szModName)/sizeof(TCHAR)))
{
//printf( "fess pid: %u modname: %s\n", processID, szModName );
if(strstr(szModName, searchStr))
{
printf( "pid: %u modname: %s\n", processID, szModName );
CloseHandle( hProcess );
return hMods[k];
}
}
}//for
}
}
CloseHandle( hProcess );
return NULL;
}
HMODULE getModule(char* searchStr){ // gets the module by the modul name from all processes
DWORD aProcesses[1024], cbNeeded, cProcesses;
if ( !EnumProcesses( aProcesses, sizeof(aProcesses), &cbNeeded ) ) return NULL;
cProcesses = cbNeeded / sizeof(DWORD);
HMODULE hmodule;
unsigned int i;
for (i = 0; i < cProcesses; ++i )
{
if(hmodule = getModulePid(aProcesses[i], searchStr))
{
return hmodule;
}
}
return NULL;
}
HMODULE getModuleHwnd(HWND hwnd){ // gets the module from a window
DWORD pid;
DWORD tid = GetWindowThreadProcessId(hwnd, &pid ); // !!??!!
printf( "hwnd tid: %u\n", tid );
printf( "hwnd pid: %u\n", pid );
return getModulePid(pid, ".exe");
}
HMODULE hModuleT;
char* searchStrT;
BOOL CALLBACK shownWindow(HWND hwnd, LPARAM lParam){ // EnumWindows callback
if(hModuleT) return TRUE;
char pcWinTitle[256];
if(GetWindow(hwnd, GW_OWNER)) return TRUE; // whats that?
GetWindowText(hwnd, pcWinTitle, 1024);
if(strstr(pcWinTitle, searchStrT))
{
printf( "wndtitle: %s\n", pcWinTitle);
hModuleT = getModuleHwnd(hwnd);
char szBuff[512];
sprintf(szBuff, "%p", hwnd);
printf( "Found .... hWnd: %s\n", szBuff);
}
return TRUE;
}
HMODULE getModuleByWndTitle(char* searchStr){ // gets the module from a window title
searchStrT = searchStr;
EnumWindows(shownWindow, 0);
return hModuleT;
}
int main()
{
//EnumWindows(EnumWindowsProc, 0);
printf("find by name ... \n");
getModule("calc.exe");
printf("\nfind by title ... \n");
getModuleByWndTitle("Calculator");
printf("Done");
return 0;
}
Basically, I have a program which will be launched more than once. So, there will be two or more processes launched of the program.
I want to use the Win32 API and kill/terminate all the processes with a specific name.
I have seen examples of killing A process, but not multiple processes with the exact same name(but different parameters).
Try below code, killProcessByName() will kill any process with name filename :
#include <windows.h>
#include <process.h>
#include <Tlhelp32.h>
#include <winbase.h>
#include <string.h>
void killProcessByName(const char *filename)
{
HANDLE hSnapShot = CreateToolhelp32Snapshot(TH32CS_SNAPALL, NULL);
PROCESSENTRY32 pEntry;
pEntry.dwSize = sizeof (pEntry);
BOOL hRes = Process32First(hSnapShot, &pEntry);
while (hRes)
{
if (strcmp(pEntry.szExeFile, filename) == 0)
{
HANDLE hProcess = OpenProcess(PROCESS_TERMINATE, 0,
(DWORD) pEntry.th32ProcessID);
if (hProcess != NULL)
{
TerminateProcess(hProcess, 9);
CloseHandle(hProcess);
}
}
hRes = Process32Next(hSnapShot, &pEntry);
}
CloseHandle(hSnapShot);
}
int main()
{
killProcessByName("notepad++.exe");
return 0;
}
Note: The code is case sensitive to filename, you can edit it for case insensitive.
I just ran into a similar problem. Here's what I came up with...
void myClass::killProcess()
{
const int maxProcIds = 1024;
DWORD procList[maxProcIds];
DWORD procCount;
char* exeName = "ExeName.exe";
char processName[MAX_PATH];
// get the process by name
if (!EnumProcesses(procList, sizeof(procList), &procCount))
return;
// convert from bytes to processes
procCount = procCount / sizeof(DWORD);
// loop through all processes
for (DWORD procIdx=0; procIdx<procCount; procIdx++)
{
// get a handle to the process
HANDLE procHandle = OpenProcess(PROCESS_ALL_ACCESS, FALSE, procList[procIdx]);
// get the process name
GetProcessImageFileName(procHandle, processName, sizeof(processName));
// terminate all pocesses that contain the name
if (strstr(processName, exeName))
TerminateProcess(procHandle, 0);
CloseHandle(procHandle);
}
}
void kill(std::string filename, int delay)
{
filename += ".exe";
HANDLE hSnapShot = CreateToolhelp32Snapshot(TH32CS_SNAPALL, NULL);
PROCESSENTRY32 pEntry;
pEntry.dwSize = sizeof(pEntry);
BOOL hRes = Process32First(hSnapShot, &pEntry);
while (hRes) {
if (filename.c_str() == pEntry.szExeFile) {
HANDLE hProcess = OpenProcess(PROCESS_TERMINATE, 0, (DWORD)pEntry.th32ProcessID);
if (hProcess != NULL) {
TerminateProcess(hProcess, 9);
CloseHandle(hProcess);
}
}
hRes = Process32Next(hSnapShot, &pEntry);
}
CloseHandle(hSnapShot);
}
// usage
int main()
{
kill("notepad");
}
I know this is old but i feel as if i should explain some of the issues and bad practice with the 2011 anwer. There is absolutely no reason for you to be writing c in c++ unless you need to. The use of const char array is unnecessary as std::string::c_str() already returns a pointer to the string. As you can see in my snippet... - filename is no longer a const char, instead its a string because its native c++ and good practice - strcmp check is removed as there is no reason to compare string differences. Instead we check if they're equivalent - We append ".exe" to filename so you can type the process name without the .exe There is simply no reason to write c in c++ unless its mandatory.