2010-10-31 20 views
7

Digamos que tengo un programa que encierra el procesador y/o el disco duro al punto que hace casi imposible hacer algo más en esa computadora. Ahora no quiero matar a ese programa porque lo que hace es útil (es un trabajo por lotes que realmente es esa CPU o disco pesado, por ejemplo, podría ZIP unos pocos gigabytes de archivos de datos) pero por un corto tiempo tengo que hacer algo más en esa computadora. ¿Hay alguna forma en que un programa externo podría congelar ese asesino de rendimiento por un tiempo?¿Cómo puedo congelar la ejecución de un programa?

Es como la antigua opción de DOS para alternar entre programas sin tener que realizar multitareas.

Supongamos que el programa hipotético en cuestión es un producto de terceros para el que no tengo el código fuente y no hay forma de decirle que pause.

Sé que puedo cambiar la clase de prioridad del programa, p. en TaskManager pero eso no es suficiente, quiero congelarlo.

Estoy hablando de Windows XP como el sistema operativo y me gustaría programar una solución con Delphi. Tengo todos los derechos en la máquina, así que podría comenzar algo como administrador, reemplazar archivos y también podría instalar un servicio si fuera necesario.

+2

Para una solución alternativa mediante el uso de DebugActiveProcess: http://stackoverflow.com/questions/11010165/ho-to -suspend-resume-a-process-in-windows/11010508 # 11010508 –

Respuesta

4

Puedes usar mi componente ProcessInfo a suspender todas las discusiones que pertenecen al proceso. El enfoque es similar a lo que Runner te explicó. El código sería algo como esto:

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; 

Puede descargar el código fuente de ProcessInfo forma here

+0

Acepto su respuesta, aunque los demás también son correctos y contienen más información sobre los detalles, pero soy flojo, así que me gusta usar un componente. – dummzeuch

+0

@vcldeveloper, ¿Cómo es esto diferente de resmon http://stackoverflow.com/a/21649539/632951? – Pacerier

14

Puede congelarlo con Process Explorer: haga clic con el botón derecho en su programa y seleccione Suspend.

Aquí hay un código de ejemplo para la congelación programática de http://www.c-plusplus.de/forum/viewtopic-var-p-is-1460293.html, editado y error se omite la comprobación de la brevedad:

#include <windows.h> 

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

Ah sí, pero ¿qué API está usando? SuspendThread en todos los hilos del proceso? http://msdn.microsoft.com/en-us/library/ms686345(v=VS.85).aspx –

+3

Conociendo a Russinovich y su conocimiento del núcleo, probablemente use NtSuspendProcess directamente. – Runner

+0

Aquí el texto en inglés http://technet.microsoft.com/en-us/sysinternals/bb896653.aspx –

6

Si desea hacerlo mediante programación se puede utilizar el enfoque descrito here.

Lo que hace es enumerar todos los hilos en un proceso y luego suspenderlos. No hay API SuspendProcess, por lo que esta es una simulación de dicha llamada.

Ten en cuenta que esto puede tener potencialmente algunos efectos secundarios negativos. Depende del proceso y de cómo está escrito.

No conozco otra forma de hacerlo en el mundo de la API Win32/64. Si baja al kernel y utiliza las API NT *, tiene disponible la API "NtSuspendProcess". Pero esto no está documentado, por lo que puede cambiar con cualquier versión de Windows o incluso con cualquier service pack (aunque no es muy probable).

La declaración de "NtSuspendProcess" se puede encontrar en los puertos JEDI de las API de 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; 

Esperanza esto ayuda

+1

usa tlhelp32; (agréguelo a la cláusula uses) – opc0de

Cuestiones relacionadas