35

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).

masoud
  • 55,379
  • 16
  • 141
  • 208
dikidera
  • 2,004
  • 6
  • 29
  • 36
  • 1
    Why don't you do what you do for killing a single process iteratively, until you fail? (no more processes to kill) – dario_ramos Oct 31 '11 at 16:26
  • Terminating a process is a dangerous operation. Why is it that you need to kill these processes? Can it be done more gracefully (such as by, say, sending all of the windows a `WM_CLOSE` message)? – Adam Rosenfield Oct 31 '11 at 16:46
  • It's a console application...well a python application CONVERTED with py2exe to an .exe and i believe the only way is to terminate it forcefully – dikidera Oct 31 '11 at 17:21

3 Answers3

63

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.

masoud
  • 55,379
  • 16
  • 141
  • 208
  • 1
    How would I make this program case insensitive? – HereToLearn Sep 27 '16 at 22:01
  • 1
    You can use another comparing function instead of `strcmp`. Follow [this](http://stackoverflow.com/questions/5820810/case-insensitive-string-comp-in-c) – masoud Sep 28 '16 at 04:56
  • 4
    `if (hProcess != NULL && pEntry.th32ProcessID != GetCurrentProcessId())` to avoid killing yourself ! ;-) – poukill Oct 13 '16 at 14:33
  • 3
    I ran into an issue trying to use your soluthing where it has issues comparing wchar with char on line 13 – Duxa Jun 23 '18 at 07:36
  • @Duxa Ran into the same problem. Any idea how to fix it? – Algo Oct 29 '21 at 17:41
  • 1
    @Duxa you can pass filename as `const wchar_t *` and use `wscmp` to compare – Amomum Nov 24 '21 at 15:47
  • in agreed with @poukill, you can use these source: void killProcess() {HANDLE hSnapShot = CreateToolhelp32Snapshot(TH32CS_SNAPALL, 0); PROCESSENTRY32 pEntry; pEntry.dwSize = sizeof(pEntry); BOOL hRes = Process32First(hSnapShot, &pEntry); pEntry.th32ProcessID = GetCurrentProcessId(); if ((HANDLE hProcess = OpenProcess( PROCESS_TERMINATE, 0, (DWORD) pEntry.th32ProcessID)) != NULL) { TerminateProcess(hProcess, 9); CloseHandle(hProcess); }CloseHandle(hSnapShot);} – Jens May 05 '23 at 06:22
2

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);    
   }
}
Jeremy Whitcher
  • 611
  • 7
  • 10
-2
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.
Trey
  • 1
  • I'm sorry, but nothing is gained here by converting a `const char[]` to a `std::string` only to append ".exe" - thereby changing the semantics of the `filename` parameter in unexpected ways (it's not a filename anymore). Note that executables may have other extensions than .exe so you needlessly limited the scope of the function. By replacing `strcmp` with `==` you introduced a bug as strings are not compared anymore, only their addresses. Let me also note that you have introduced an unreferenced and therefore useless `delay` parameter. – purefanatic Jun 25 '20 at 19:10
  • A `string_view` _might_ be a C++ improvement over the original code but it is still fine as is. Even if your answer provided some actual "C++ improvement" - not just a little nicer syntax - it would still have been misplaced as the asker never asked for C++, only for C (see the question tags). Please don't feel bad but think through your next answers a bit more thoroughly. Also, as long as you are not very comfortable with what you are doing I recommend always running your code before posting it. This way you should be able to eliminate the more obvious bugs and misunderstandings beforehand. – purefanatic Jun 25 '20 at 19:21