2009-12-16 9 views
7

Ich schreibe gerade ein sehr leichtgewichtiges Programm, also muss ich C++ verwenden, da es nicht an .NET Framework gebunden ist, was die Größe des Programms drastisch erhöht.Wie kündigen Sie effektiv einen Prozess in C++ (Win32)?

Ich muss in der Lage sein, Prozess zu beenden, und dazu muss ich einen Prozess behandeln. Leider habe ich noch nicht herausgefunden, wie ich das machen soll.

P.S. Ich weiß, dass, um einen Prozess zu töten, müssen Sie TerminateProcess verwenden.

+0

Ich habe pgrep und pkill in der Vergangenheit sieht, aber das war während Solaris Tage. –

+1

Sie meinen in Win32. Nichts ist mit C++ hier verbunden – KeatsPeeks

+0

Ähm ... yeah hast du Recht –

Antwort

11

Die PID Sie für Open müssen gearbeitet() ist normalerweise nicht leicht, einen zu ergattern. Wenn Sie nur einen Prozessnamen haben, müssen Sie die laufenden Prozesse auf dem Computer wiederholen. Tun Sie dies mit CreateToolhelp32Snapshot, gefolgt von Process32First und Schleife mit Process32Next. Die PROCESSENTRY32.szExeFile gibt Ihnen den Prozessnamen (nicht Pfad!), Th32ProcessID gibt Ihnen die PID.

Die nächste Überlegung ist, dass der Prozess möglicherweise mehr als einmal angezeigt wird. Und es besteht die Möglichkeit, dass derselbe Prozessname für sehr unterschiedliche Programme verwendet wird. Wie "Setup". Wenn Sie nicht nur alle töten wollen, müssen Sie versuchen, einige Laufzeit-Informationen von ihnen zu erhalten. Fensterbeschriftungsleiste, vielleicht. GetProcessImageFileName() kann Ihnen den Pfad zu der EXE-Datei angeben. Es verwendet das native Kernel-Format. Sie müssen QueryDosDevice verwenden, um den Laufwerksgerätnamen einem Laufwerkbuchstaben zuzuordnen.

Die nächste Überlegung ist die Rechte, die Sie in OpenProcess() fragen. Sie werden wahrscheinlich PROCESS_ALL_ACCESS nicht bekommen, alles, was Sie brauchen, ist PROCESS_TERMINATE. Obwohl das auch privilegiert ist. Stellen Sie sicher, dass das Konto, das Sie zum Ausführen Ihres Programms verwenden, dieses Recht erhalten kann.

1

CreateProcess und OpenProcess Rückgabehandles.

Hier finden Sie einige sample code, um einen Prozess zu finden, indem Sie das System auffordern, alle Prozesse aufzulisten und dann die Liste nach dem gewünschten Prozess zu durchsuchen.

+0

Also mit OpenProcess mit einer Prozess-ID wird mir Zugang zu dem Prozess geben? –

5

Verwenden Sie OpenProcess in Kombination mit einer anderen Funktion wie EnumProcesses, um ein Handle zu TerminateProcess zu übergeben.

+0

GetWindowThreadProcessId könnte vielleicht verwendet werden: http://msdn.microsoft.com/en-us/library/ms633522%28VS.85%29.aspx – dalle

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

Das

+2

Nicht vergessen 'CloseHandle (Explorer)' – slater

10

Anstatt durch all diesen Schmerz zu gehen, um einen Prozess mit einem bekannten Namen zu töten, warum rufen Sie nicht einfach nach "System" und bitten Sie die Befehlszeile, es zu töten?

Zum Beispiel

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

Nicht sicher, dass dies 'lighweight ". Es ist bekannt, dass "System" langsam ist. –

+1

Gemäß dieser Frage bezieht sich "leicht" auf "leicht in der Größe" und daher würde "System" in diesem Fall "leichtgewichtig" sein. –

+1

Dies ist eine einfache und elegante Lösung und funktioniert wie ein Charme. –

0

Hier sind einige Arbeitsbeispielcodes einen Prozess zu töten, genannt "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

Hier ist das vollständige Beispiel für Visual Studio 2010 C++ Projekt wie um den Prozess durch den Dateinamen EXE zu beenden.

Um dies zu überprüfen, führen Sie einfach den Internet Explorer aus und führen Sie den folgenden Code aus.

#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; 
} 

in C# Stellen Sie sich vor es wie

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

Fenster nur

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