web-dev-qa-db-fra.com

Comment tuer efficacement un processus en C++ (Win32)?

J'écris actuellement un programme très léger et je dois donc utiliser le C++ car il n'est pas lié au .NET Framework, ce qui augmente considérablement la taille du programme.

Je dois pouvoir mettre fin au processus et faire cela, je dois obtenir un descripteur de processus. Malheureusement, je n'ai pas encore compris comment faire cela.

P.S. Je sais que pour tuer un processus, vous devez utiliser TerminateProcess .

12
Kristina Brooks

Le PID dont vous avez besoin pour OpenProcess () n’est normalement pas facile à obtenir. Si tout ce que vous avez est un nom de processus, vous devez itérer les processus en cours d'exécution sur la machine. Faites-le avec CreateToolhelp32Snapshot, suivi de Process32First et boucle avec Process32Next. PROCESSENTRY32.szExeFile vous donne le nom du processus (pas le chemin!), Th32ProcessID vous donne le PID.

La considération suivante est que le processus peut apparaître plus d'une fois. Et il est possible que le même nom de processus soit utilisé pour des programmes très différents. Comme "Setup". Si vous ne voulez pas simplement tous les tuer, vous devrez essayer d'obtenir des informations d'exécution à leur sujet. Texte de la barre de légende de la fenêtre, peut-être. GetProcessImageFileName () peut vous donner le chemin du fichier .exe. Il utilise le format de noyau natif. QueryDosDevice est nécessaire pour mapper un nom de périphérique de lecteur de disque sur une lettre de lecteur.

La considération suivante concerne les droits que vous demandez dans OpenProcess (). Il est peu probable que vous obteniez PROCESS_ALL_ACCESS, tout ce dont vous avez besoin est PROCESS_TERMINATE. Bien que ce soit également privilégié. Assurez-vous que le compte que vous utilisez pour exécuter votre programme peut obtenir ce droit.

15
Hans Passant

Plutôt que de passer par toute cette douleur pour tuer un processus avec un nom connu, pourquoi ne pas simplement appeler "système" et demander à la ligne de commande de le tuer?

Par exemple,

int retval = ::_tsystem( _T("taskkill /F /T /IM MyProcess.exe") );
12
James Hugard

Pour obtenir un descripteur à transmettre à TerminateProcess , utilisez OpenProcess en combinaison avec une autre fonction telle que EnumProcesses .

5
Jon Benedicto
HANDLE Explorer;
Explorer = OpenProcess(PROCESS_ALL_ACCESS,false,2120);
TerminateProcess(Explorer,1);

Ça a marché

5
Kristina Brooks

Voici l'exemple complet du projet Visual Studio 2010 C++: comment tuer le processus à l'aide du nom de fichierEXE.

Pour le vérifier, lancez simplement Internet Explorer, puis exécutez le code suivant.

#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 en C # on dirait 

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();
                }
            }
        }
    }
}
3

CreateProcess et OpenProcess Le processus de retour renvoie.

Voici quelques exemple de code pour trouver un processus en demandant au système de répertorier tous les processus, puis en recherchant le processus souhaité.

1
Jason Orendorff

Voici quelques exemples de codes de travail pour tuer un processus appelé "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);
                }
            }
        }
    }
}
0
laishiekai

fenêtres seulement

system("taskkill /f /im servicetokill.exe")
0
user3290207