22

I am currently writing a very lightweight program so I have to use C++ since it is not bound to .NET framework which drastically increases size of the program.

I need to be able to terminate process and to do that I need to get a process handle. Unfortuanately I haven't figured how to do that yet.

P.S. I know that to kill a process you have to use TerminateProcess.

Kristina
  • 15,859
  • 29
  • 111
  • 181

9 Answers9

19

The following code works:

const auto explorer = OpenProcess(PROCESS_TERMINATE, false, process_id);
TerminateProcess(explorer, 1);
CloseHandle(explorer);
BullyWiiPlaza
  • 17,329
  • 10
  • 113
  • 185
Kristina
  • 15,859
  • 29
  • 111
  • 181
19

Rather than going through all that pain to kill a process with a known name, why not simply call out to "system" and ask the command-line to kill it?

For example,

int retval = ::_tsystem( _T("taskkill /F /T /IM MyProcess.exe") );
Ehsan Khodarahmi
  • 4,772
  • 10
  • 60
  • 87
James Hugard
  • 3,232
  • 1
  • 25
  • 36
  • Not sure this satisfies 'lighweight'. `system` is well known to be slow. – Mike Kwan Mar 01 '12 at 20:06
  • 1
    According to this question, 'lightweight' refers to "light in size" and hence 'system' would satisfy 'lightweight' in this case. – Vikram Singh Mar 08 '13 at 17:31
  • 1
    This is a simple and elegant solution and works like a charm. – Brandon Bearden Oct 18 '13 at 22:05
  • 15
    Simple and elegant? that's not true. – Didac Perez Parera Dec 04 '13 at 14:39
  • 4
    Yes, works usually. But it involves too many assumptions for my taste: that taskkill.exe is in the path, that the taskkill.exe that is found is actually the one you want, that the command line arguments haven't been changed by a newer version of taskkill.exe, that the WMI service is running. – John Fitzpatrick Jul 18 '16 at 09:27
  • what if you have multiple instances of that program running? I suspect this would kill all of them, while using a PID will not have this problem – AndrewBloom Feb 21 '21 at 14:29
18

The PID you need for OpenProcess() is not normally easy to get a hold of. If all you got is a process name then you need to iterate the running processes on the machine. Do so with CreateToolhelp32Snapshot, followed by Process32First and loop with Process32Next. The PROCESSENTRY32.szExeFile gives you the process name (not path!), th32ProcessID gives you the PID.

The next consideration is that the process may appear more than once. And there's a chance that the same process name is used for very different programs. Like "Setup". If you don't just want to kill them all, you'll need to try to obtain some runtime info from them. Window caption bar text, perhaps. GetProcessImageFileName() can give you the path to the .exe. It uses the native kernel format, you'd need QueryDosDevice to map a disk drive device name to a drive letter.

The next consideration is the rights you ask for in OpenProcess(). You are unlikely to get PROCESS_ALL_ACCESS, all you need is PROCESS_TERMINATE. Although that's privileged as well. Ensure the account you use to run your program can obtain that right.

Hans Passant
  • 922,412
  • 146
  • 1,693
  • 2,536
6

Here is the full example for Visual Studio 2010 C++ project how to kill the process by the EXE file name.

In order to check it just run Internet Explorer and after this execute following code.

#include <iostream>
#include <string>
#include<tchar.h>
#include <process.h>
#include <windows.h>
#include <tlhelp32.h>

using namespace std;

//  Forward declarations:
BOOL GetProcessList();
BOOL TerminateMyProcess(DWORD dwProcessId, UINT uExitCode);

int main( void )
{
  GetProcessList( );
  return 0;
}

BOOL GetProcessList( )
{
  HANDLE hProcessSnap;
  HANDLE hProcess;
  PROCESSENTRY32 pe32;
  DWORD dwPriorityClass;

  // Take a snapshot of all processes in the system.
  hProcessSnap = CreateToolhelp32Snapshot( TH32CS_SNAPPROCESS, 0 );
  if( hProcessSnap == INVALID_HANDLE_VALUE )
  {   
    return( FALSE );
  }

  // Set the size of the structure before using it.
  pe32.dwSize = sizeof( PROCESSENTRY32 );

  // Retrieve information about the first process,
  // and exit if unsuccessful
  if( !Process32First( hProcessSnap, &pe32 ) )
  {   
    CloseHandle( hProcessSnap );  // clean the snapshot object
    return( FALSE );
  }

  // Now walk the snapshot of processes 
  do
  {  
    string str(pe32.szExeFile);

    if(str == "iexplore.exe") // put the name of your process you want to kill
    {
        TerminateMyProcess(pe32.th32ProcessID, 1);
    } 
  } while( Process32Next( hProcessSnap, &pe32 ) );

  CloseHandle( hProcessSnap );
  return( TRUE );
}

BOOL TerminateMyProcess(DWORD dwProcessId, UINT uExitCode)
{
    DWORD dwDesiredAccess = PROCESS_TERMINATE;
    BOOL  bInheritHandle  = FALSE;
    HANDLE hProcess = OpenProcess(dwDesiredAccess, bInheritHandle, dwProcessId);
    if (hProcess == NULL)
        return FALSE;

    BOOL result = TerminateProcess(hProcess, uExitCode);

    CloseHandle(hProcess);

    return result;
}

Imagine in C# it looks like

using System;
using System.Collections.Generic;
using System.Text;

namespace MyProcessKiller
{
    class Program
    {
        static void Main(string[] args)
        {
            foreach (System.Diagnostics.Process myProc in System.Diagnostics.Process.GetProcesses())
            {
                if (myProc.ProcessName == "iexplore")
                {
                    myProc.Kill();
                }
            }
        }
    }
}
NoWar
  • 36,338
  • 80
  • 323
  • 498
5

To get a handle to pass to TerminateProcess, use OpenProcess in combination with some other function like EnumProcesses.

Jon Benedicto
  • 10,492
  • 3
  • 28
  • 30
  • GetWindowThreadProcessId could perhaps be used: http://msdn.microsoft.com/en-us/library/ms633522%28VS.85%29.aspx – dalle Dec 16 '09 at 19:10
4

windows only

system("taskkill /f /im servicetokill.exe")
Dmitriy
  • 5,525
  • 12
  • 25
  • 38
user3290207
  • 55
  • 1
  • 6
2

Here are some working sample codes to kill a process called "ShouldBeDead.exe":

// you will need these headers, and you also need to link to Psapi.lib
#include <tchar.h>
#include <psapi.h>

...
// first get all the process so that we can get the process id 
DWORD processes[1024], count;
if( !EnumProcesses( processes, sizeof(processes), &count ) )
{
    return false;
}

count /= sizeof(DWORD);
for(unsigned int i = 0; i < count; i++)
{
    TCHAR szProcessName[MAX_PATH] = TEXT("<unknown>");
    if(processes[i] != 0)
    {
        // remember to open with PROCESS_ALL_ACCESS, otherwise you will not be able to kill it
        HANDLE hProcess = OpenProcess( PROCESS_ALL_ACCESS, FALSE, processes[i] );
        if(NULL != hProcess)
        {
            HMODULE hMod;
            DWORD cbNeeded;
            if(EnumProcessModules(hProcess, &hMod, sizeof(hMod), &cbNeeded))
            {
                GetModuleBaseName(hProcess, hMod, szProcessName, sizeof(szProcessName)/sizeof(TCHAR));

                // find the process and kill it
                if(strcmp(szProcessName, "ShouldBeDead.exe") == 0)
                {
                    DWORD result = WAIT_OBJECT_0;
                    while(result == WAIT_OBJECT_0)
                    {
                        // use WaitForSingleObject to make sure it's dead
                        result = WaitForSingleObject(hProcess, 100);
                        TerminateProcess(hProcess, 0);
                    }

                    CloseHandle(hProcess);
                }
            }
        }
    }
}
laishiekai
  • 841
  • 1
  • 13
  • 26
1

CreateProcess and OpenProcess return process handles.

Here's some sample code to find a process by asking the system to list all processes and then searching the list for the process you want.

Jason Orendorff
  • 42,793
  • 6
  • 62
  • 96
-1

Task Killer using Modern C++

Below is the code I've created for my Terminator Program

//_____________________________________________
//                                             |
// TheNexGen of Terminator (inclusion version) |
// ------------------------------------------- |
//                                             |
// Add your Programs in the 'if' check as I've |
// listed below, and compile using c++17 flag  |
// or higher                                   |
//_____________________________________________|



#include <process.h>
#include <windows.h>
#include <tlhelp32.h>
#include <string_view>
using namespace std;

int main()
{
    HANDLE hProcessSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
    if (hProcessSnap == INVALID_HANDLE_VALUE) return 0;

    PROCESSENTRY32W pe32{ .dwSize = sizeof(PROCESSENTRY32) };
    if (!Process32First(hProcessSnap, &pe32)) return CloseHandle(hProcessSnap), 0;

    do
    {
        wstring_view str = pe32.szExeFile;

        if
            (
                str == L"chrome.exe"
                || str == L"AAM Update Notifier.exe"
                || str == L"About.exe"
                || str == L"ActionCenterDownloader.exe"
                || str == L"adb.exe"
                || str == L"AdobeARM.exe"
            )
        {
            if (HANDLE hProcess = OpenProcess(PROCESS_TERMINATE, 0, pe32.th32ProcessID))
            {
                TerminateProcess(hProcess, 1);
                CloseHandle(hProcess);
            }
        }
    }
    while (Process32Next(hProcessSnap, &pe32));

    CloseHandle(hProcessSnap);
}

Description

Increased Execution Speed 100x of the Code provided by @DmitryBoyko.

The MR
  • 19