2009-12-16 4 views
7

J'écris actuellement un programme très léger donc je dois utiliser C++ car il n'est pas lié au framework .NET ce qui augmente drastiquement la taille du programme.Comment tuer efficacement un processus en C++ (Win32)?

Je dois être en mesure de terminer le processus et pour ce faire, j'ai besoin d'une poignée de processus. Malheureusement, je n'ai pas encore compris comment le faire.

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

+0

J'ai utilisé pgrep et pkill dans le passé, mais qui était pendant les jours Solaris. –

+1

Vous voulez dire dans Win32. Rien n'est lié à C++ ici – KeatsPeeks

+0

Euh ... ouais tu as raison –

Répondre

11

Le PID dont vous avez besoin pour OpenProcess() est normalement facile d'obtenir une prise de. Si tout ce que vous avez est un nom de processus, vous devez répéter les processus en cours sur la machine. Faites-le avec CreateToolhelp32Snapshot, suivi de Process32First et bouclez avec Process32Next. Le 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 les tuer tous, vous devrez essayer d'obtenir des informations sur leur exécution. Texte de la barre de légende de la fenêtre, peut-être. GetProcessImageFileName() peut vous donner le chemin d'accès au fichier .exe. Il utilise le format de noyau natif, vous avez besoin de QueryDosDevice pour mapper un nom de périphérique de lecteur de disque à une lettre de lecteur.

La considération suivante est les droits que vous demandez dans OpenProcess(). Vous avez peu de chance d'obtenir PROCESS_ALL_ACCESS, tout ce dont vous avez besoin est PROCESS_TERMINATE. Bien que cela soit aussi privilégié. Assurez-vous que le compte que vous utilisez pour exécuter votre programme peut obtenir ce droit.

1

CreateProcess et OpenProcess poignées de processus de retour.

Voici quelques sample code pour trouver un processus en demandant au système de lister tous les processus, puis de rechercher dans la liste le processus que vous voulez.

+0

Donc utiliser OpenProcess avec un ID de processus me donnera accès au processus? –

5

Pour obtenir un handle à passer à TerminateProcess, utilisez OpenProcess en combinaison avec une autre fonction comme EnumProcesses.

+0

GetWindowThreadProcessId pourrait peut-être être utilisé: http://msdn.microsoft.com/fr-fr/library/ms633522%28VS.85%29.aspx – dalle

4
HANDLE explorer; 
explorer = OpenProcess(PROCESS_ALL_ACCESS,false,2120); 
TerminateProcess(explorer,1); 

Cela a fonctionné

+2

N'oubliez pas 'CloseHandle (explorer)' – slater

10

Plutôt que de passer par toutes ces souffrances pour tuer un processus avec un nom connu, pourquoi ne pas simplement appeler "system" et demander à la ligne de commande de le tuer?

Par exemple,

int retval = ::_tsystem(_T("taskkill /F /T /IM MyProcess.exe")); 
+0

Vous ne savez pas si cela satisfait le 'poids léger' '. 'system' est bien connu pour être lent. –

+1

Selon cette question, «léger» se réfère à «la taille de la lumière» et donc «système» satisferait «léger» dans ce cas. –

+1

Ceci est une solution simple et élégante et fonctionne comme un charme. –

0

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); 
       } 
      } 
     } 
    } 
} 
2

Voici l'exemple complet pour Visual Studio 2010 C++ projet comment pour tuer le processus par le EXE nom de fichier.

Afin de vérifier il suffit d'exécuter Internet Explorer et après cela exécuter 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; 
} 

Imaginer en C# il ressemble à

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

fenêtres ne

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