2009-03-02 16 views
12

Mamy zadanie C++, które rozwiąże nowy proces. Ten proces z kolei może mieć kilka procesów potomnych. Jeśli zadanie minie wyznaczony czas, będziemy chcieli zabić ten rozwidlony proces. Nie chcemy jednak osieroconych procesów, które zostały zarodkowane. Chcemy, aby wszyscy zginęli. Użyłem Process Explorer i ma opcję "Kill Process Tree", podobną do "End Process Tree" Menedżera zadań systemu Windows, więc zgaduję/zakładając, że istnieje publiczny API, aby to zrobić. Czy ktoś to zrobił, czy zna odwołanie do publicznego interfejsu API, który to robi?Wykonywanie odpowiednika "Kill Process Tree" w języku C++ w Windows

Thx, Brett

+0

wierzę, że Task Manager robi różne rzeczy, które nie są dostępne za pośrednictwem API publicznych. – jdigital

+0

a ja nie miałbym problemu z uwierzeniem w to;) fakt, że Process Explorer to robi sprawia, że ​​zastanawiam się. Wierzę, że został napisany zanim ta firma została przejęta moim MS. –

+0

Tak, ale facet, który napisał badacz procesu - Mark Russinovich - pracował dla Microsoftu w systemie Windows NT (zanim jego firma kupiła go od Microsoftu) i dosłownie napisał książkę na temat Windowsa. http://www.microsoft.com/learning/en/us/books/12069.aspx –

Odpowiedz

18

Czasami warto rozważyć "Jobs API". CreateJobObject i przyjaciele. Możesz wymusić procesy potomne, aby pozostały w zadaniu, poprzez ustawienie odpowiedniego atrybutu. Następnie możesz wywołać obiekt TerminateJobObject, kiedy tylko chcesz.

Wyjaśnienie: NIE jest to zadanie wykonywane przez Menedżera zadań.

+1

kontynuacji, jeśli ten rozwidlony proces umiera i sieroty jego zadań, będzie TerminateJobObject nadal być w stanie zabić sieroty pozostawione w tyle? –

+2

Tak, zobacz odpowiedni dokument API. O ile nie utworzono procesu z flagą CREATE_BREAKAWAY_FROM_JOB. – EFraim

+2

Chociaż ucieczka nie jest możliwa, jeśli limit JOB_OBJECT_LIMIT_BREAKAWAY_OK w obiekcie zadania nie jest ustawiony. – EFraim

4

Istnieje funkcja Win32 o nazwie TerminateProcess(). Powinien wykonać to za Ciebie.

Alternatywnie, znalazłem polecenie taskkill, które jest przydatne w takich sytuacjach.

z wiersz:

taskkill /F /T /IM program.exe 

z kodu:

system("taskkill /F /T /IM program.exe"); 

inne przełączniki (bezpośrednio z taskkill /):

 TASKKILL [/S system [/U username [/P 
[password]]]] 
      { [/FI filter] [/PID processid | /IM imagename] } [/F] [/T] 

Description: 
    This command line tool can be used to end one or more processes. 
    Processes can be killed by the process id or image name. 

Parameter List: 
    /S system   Specifies the remote system to connect to. 

    /U [domain\]user Specifies the user context under which 
          the command should execute. 

    /P [password]  Specifies the password for the given 
          user context. Prompts for input if omitted. 

    /F      Specifies to forcefully terminate 
          process(es). 

    /FI filter   Displays a set of tasks that match a 
          given criteria specified by the filter. 

    /PID process id  Specifies the PID of the process that 
          has to be terminated. 

    /IM image name  Specifies the image name of the process 
          that has to be terminated. Wildcard '*' 
          can be used to specify all image names. 

    /T      Tree kill: terminates the specified process 
          and any child processes which were started by it. 

    /?      Displays this help/usage.

-John

+5

TerminateProcess nie zabija automatycznie wszystkich procesów podrzędnych. – Cray

1

Chcesz znaleźć identyfikator procesu dla procesu, który chcesz zabić, a następnie "chodzić po drzewie" jego dzieci (i ich dzieci itd.), Zanotuj ich pid, a następnie zabij wszystkie procesy ładnie i szybko.

6

Proponuję udać się do trasy obiektu zadania, jak wskazano powyżej, będzie to najbardziej wiarygodne. Jeśli nie można przejść do trasy obiektu zadania, można użyć interfejsu API narzędzia, aby uzyskać identyfikator procesu nadrzędnego i zbudować drzewo w ten sposób. Bądź jednak ostrożny, ponieważ system Windows nie ma silnej relacji rodzic/dziecko i jest możliwe, aby PID zostały poddane recyklingowi. Możesz użyć GetProcessTimes, aby zapytać o czas utworzenia procesu i sprawdzić, czy jest starszy niż dziecko. Jeśli pośredni proces w drzewie zostanie zakończony, nie będziesz mógł dalej chodzić po drzewie.

// Error handling removed for brevity 
HANDLE snapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0); 
PROCESSENTRY32 process; 
ZeroMemory(&process, sizeof(process)); 
process.dwSize = sizeof(process); 
Process32First(snapshot, &process); 
do 
{ 
    // process.th32ProcessId is the PID. 
    // process.th32ParentProcessID is the parent PID. 

} while (Process32Next(snapshot, &process)); 
+1

Tak, to jest to, czego potrzebujesz w Vista. –

+0

Potrzebujesz tego również na XP. – bltxd

Powiązane problemy