2010-10-31 12 views
7

Dire che ho un programma che accelera il processore e/o il disco rigido al punto che rende quasi impossibile fare qualsiasi altra cosa su quel computer. Ora non voglio uccidere quel programma perché quello che fa è utile (è un lavoro batch che è davvero pesante per CPU o disco, ad esempio potrebbe ZIP qualche gigabyte di file di dati) ma per un breve periodo ho bisogno di fare qualcos'altro su quel computer. C'è un modo in cui un programma esterno potrebbe fare per congelare quel killer delle prestazioni per un po '?Come posso bloccare l'esecuzione di un programma?

È come la vecchia opzione DOS per passare da un programma all'altro senza avere effettivamente il multitasking.

Supponiamo che l'ipotetico programma in questione sia un prodotto di terze parti per il quale non ho il codice sorgente e non c'è modo di dirlo di mettere in pausa.

So che posso modificare la classe di priorità del programma, ad es. in TaskManager ma non è abbastanza, voglio bloccarlo.

Sto parlando di Windows XP come sistema operativo e vorrei programmare una soluzione con Delphi. Ho tutti i diritti sulla macchina, quindi potrei iniziare qualcosa come amministratore, sostituire i file e potrei anche installare un servizio se necessario.

+2

Per una soluzione alternativa usando usando DebugActiveProcess: http://stackoverflow.com/questions/11010165/ho-to -suspend-resume-a-process-in-windows/11010508 # 11010508 –

risposta

4

È possibile utilizzare la mia componente ProcessInfo di sospendere tutte le discussioni che appartengono al processo. L'approccio è simile a quello che Runner ti ha spiegato. Il codice potrebbe essere qualcosa di simile:

var 
    Process : TProcessItem; 
    AThread: TThreadItem; 
begin 
    Process := ProcessInfo1.RunningProcesses.FindByName('notepad.exe'); 
    if Assigned(Process) then 
    begin 
    for AThread in Process.Threads do 
     AThread.SuspendThread; 
    end; 
end; 

È possibile scaricare il codice sorgente di ProcessInfo forma here

+0

Accetto la tua risposta anche se anche gli altri sono corretti e contengono più informazioni sulle specifiche, ma sono pigro, quindi mi piace usare un componente. – dummzeuch

+0

@vcldeveloper, Com'è diverso dal resmon http://stackoverflow.com/a/21649539/632951? – Pacerier

14

È possibile congelarlo con Process Explorer: fare clic con il tasto destro del mouse sul programma e selezionare Suspend.

Ecco alcuni esempi di codice per il congelamento programmatica da http://www.c-plusplus.de/forum/viewtopic-var-p-is-1460293.html, a cura e l'errore omesso controllo per brevità:

#include <windows.h> 

_NtSuspendProcess NtSuspendProcess = 
    (_NtSuspendProcess) GetProcAddress(GetModuleHandle("ntdll"), 
             "NtSuspendProcess"); 
HANDLE ProcessHandle = OpenProcess(PROCESS_ALL_ACCESS, FALSE, pid); 
NtSuspendProcess(ProcessHandle); 
+1

Ah sì, ma quale chiama API sta utilizzando? SuspendThread su tutti i thread del processo? http://msdn.microsoft.com/en-us/library/ms686345(v=VS.85).aspx –

+3

Conoscendo Russinovich e la sua conoscenza del Kernel probabilmente usa direttamente NtSuspendProcess. – Runner

+0

Qui il testo in inglese http://technet.microsoft.com/en-us/sysinternals/bb896653.aspx –

6

Se volete farlo programatically è possibile utilizzare l'approccio descritto here.

Ciò che è, è enumerare tutti i thread in un processo e quindi sospenderli. Non ci sono API SuspendProcess, quindi questa è una simulazione di tale chiamata.

Attenzione che questo può potenzialmente avere alcuni effetti collaterali negativi. Dipende dal processo e da come è scritto.

Non conosco altro modo per farlo nel mondo delle API Win32/64. Se si scende al livello del kernel e si utilizzano le API NT *, è disponibile l'API "NtSuspendProcess". Ma questo non è documentato in modo che possa cambiare con qualsiasi versione di Windows o anche con qualsiasi service pack (non molto probabilmente però).

La dichiarazione di "NtSuspendProcess" può essere trovata nelle porte JEDI delle API di Windows.

2
function OpenThread(dwDesiredAccess: DWORD; InheritHandle: Boolean; dwThreadID: DWORD): THandle; stdcall; external 'kernel32.dll'; 

function ResumeProcess(PID: DWORD):Boolean; 
var 
    tid, snap: THandle; 
    TE32: TThreadEntry32; 
begin 
    Result := False; 
    snap := CreateToolHelp32SnapShot(TH32CS_SNAPTHREAD, 0); 
    TE32.dwSize := SizeOf(TThreadEntry32); 
    Thread32First(snap, TE32); 
    repeat 
    if TE32.th32OwnerProcessID = PID then begin 
     tid := OpenThread($0002, FALSE, TE32.th32ThreadID); 
     ResumeThread(tid); 
     Result := TRUE; 
     CloseHandle(tid); 
    end; 
    until Thread32Next(snap, TE32) = false; 
    CloseHandle(snap); 
end; 

function SuspendProcess(PID: DWORD): Boolean; 
var 
    tid, snap: THandle; 
    TE32: TThreadEntry32; 
begin 
    Result := False; 
    snap := CreateToolHelp32SnapShot(TH32CS_SNAPTHREAD, 0); 
    TE32.dwSize := SizeOf(TThreadEntry32); 
    Thread32First(snap, TE32); 
    repeat 
    if TE32.th32OwnerProcessID = PID then begin 
     tid := OpenThread($0002, FALSE, TE32.th32ThreadID); 
     SuspendThread(tid); 
     Result := TRUE; 
     CloseHandle(tid); 
    end; 
    until Thread32Next(snap, TE32) = false; 
    CloseHandle(snap); 
end; 

Spero che questo aiuti

+1

utilizza tlhelp32; (aggiungilo nella clausola dei tuoi usi) – opc0de

Problemi correlati