2009-12-16 30 views
7

Actualmente estoy escribiendo un programa muy liviano, así que tengo que usar C++ ya que no está vinculado a .NET framework, que aumenta drásticamente el tamaño del programa.¿Cómo matar eficazmente un proceso en C++ (Win32)?

Necesito poder terminar el proceso y para hacer eso necesito obtener un identificador de proceso. Desafortunadamente, todavía no he pensado cómo hacerlo.

P.S. Sé que para matar un proceso, debe usar TerminateProcess.

+0

he utilizado pgrep y pkill en el pasado, pero eso fue durante los días de Solaris. –

+1

¿Quieres decir en Win32. Nada está relacionado con C++ aquí – KeatsPeeks

+0

Um ... sí, tienes razón –

Respuesta

11

El PID lo necesario para OpenProcess() normalmente no es fácil conseguir un asimiento de. Si todo lo que tiene es un nombre de proceso, entonces necesita iterar los procesos en ejecución en la máquina. Hágalo con CreateToolhelp32Snapshot, seguido de Process32First y bucle con Process32Next. El PROCESSENTRY32.szExeFile le proporciona el nombre del proceso (¡no la ruta!), Th32ProcessID le proporciona el PID.

La siguiente consideración es que el proceso puede aparecer más de una vez. Y existe la posibilidad de que el mismo nombre de proceso se use para programas muy diferentes. Como "Configuración". Si no solo quieres matarlos a todos, deberás tratar de obtener alguna información de tiempo de ejecución de ellos. Texto de la barra de título de la ventana, tal vez. GetProcessImageFileName() puede darle la ruta al .exe. Utiliza el formato de núcleo nativo, necesitaría QueryDosDevice para asignar el nombre de un dispositivo de unidad de disco a una letra de unidad.

La siguiente consideración son los derechos que solicita en OpenProcess(). Es poco probable que obtenga PROCESS_ALL_ACCESS, todo lo que necesita es PROCESS_TERMINATE. Aunque eso también es privilegiado. Asegúrese de que la cuenta que usa para ejecutar su programa pueda obtener ese derecho.

1

CreateProcess y OpenProcess return process handles.

Aquí hay algunos sample code para encontrar un proceso pidiéndole al sistema que liste todos los procesos y luego busque en la lista el proceso que desee.

+0

Entonces, si uso OpenProcess con un ID de proceso, ¿tendré acceso al proceso? –

5

Para obtener un asa para pasar a TerminateProcess, use OpenProcess en combinación con alguna otra función como EnumProcesses.

+0

GetWindowThreadProcessId podría quizás utilizarse: 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); 

que funcionó

+2

No se olvide 'CloseHandle (explorer)' – slater

10

En lugar de pasar por todo ese dolor para matar un proceso con un nombre conocido, ¿por qué no simplemente llamar al "sistema" y pedirle a la línea de comandos que lo mate?

Por ejemplo,

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

No estoy seguro de que esto satisfaga 'lighweight '. 'system' es bien conocido por ser lento. –

+1

De acuerdo con esta pregunta, "peso ligero" se refiere a "luz de tamaño" y, por lo tanto, "sistema" satisfaría "peso ligero" en este caso. –

+1

Esta es una solución simple y elegante y funciona como un encanto. –

0

Éstos son algunos ejemplos de códigos de trabajo de matar a un proceso llamado "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

Aquí está el ejemplo completo para proyecto de Visual Studio 2010 C++ cómo para matar el proceso por el EXE nombre de archivo.

Para comprobarlo simplemente ejecute Internet Explorer y luego ejecute el siguiente código.

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

imaginar en C# parece que

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

ventanas sólo

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