Как я могу заморозить выполнение программы?

скажем, у меня есть программа, которая забивает процессор и/или жесткий диск до такой степени, что практически невозможно сделать что-либо еще на этом компьютере. Теперь я не хочу убивать эту программу, потому что то, что она делает, полезно (это пакетное задание, которое действительно является тяжелым процессором или диском, например, он может ZIP несколько гигабайт файлов данных), но на короткое время мне нужно сделать что-то еще на этом компьютере. Есть ли способ, которым внешняя программа может заморозить этот убийца производительности для пока?

Это похоже на старую опцию DOS для переключения между программами без фактической многозадачности.

предположим, что гипотетическая программа, о которой идет речь, является сторонним продуктом, для которого у меня нет исходного кода, и нет способа сказать ему приостановить.

Я знаю, что могу изменить класс приоритета программы, например, в TaskManager, но этого недостаточно, я хочу его заморозить.

Я говорю о Windows XP в качестве ОС и хотел бы запрограммируйте решение с помощью Delphi. У меня есть все права на машину, поэтому я могу запустить что-то как администратор, заменить файлы, а также установить службу, если это необходимо.

4 ответов


вы можете использовать my ProcessInfo компонент для приостановки всех потоков, принадлежащих процессу. Подход аналогичен тому, что объяснил Вам раннер. Код будет примерно таким:

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;

вы можете скачать исходный код ProcessInfo форма здесь


Вы можете заморозить его с Процесс Explorer щелкните правой кнопкой мыши на программе и выберите Suspend.

вот пример кода для программного замораживания из http://www.c-plusplus.de/forum/viewtopic-var-p-is-1460293.html, отредактировано и опущено проверка ошибок для краткости:

#include <windows.h>

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

Если вы хотите сделать это программно, вы можете использовать описанный подход здесь.

Что делает, перечисляет все потоки в процессе, а затем приостанавливает их. API SuspendProcess отсутствует, поэтому это симуляция такого вызова.

остерегайтесь, что это может потенциально иметь некоторые плохие побочные эффекты. Это зависит от процесса и от того, как он написан.

Я не знаю другого способа сделать это в мире Win32 / 64 API. Если ты уйдешь ... ниже к Земле ядра и используйте API NT*, у вас есть API "NtSuspendProcess". Но это недокументировано, поэтому он может измениться с любой версией windows или даже с любым пакетом обновления (не очень вероятно, хотя).

объявление "NtSuspendProcess"можно найти в портах JEDI API windows.


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(02, 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(02, FALSE, TE32.th32ThreadID);
      SuspendThread(tid);
      Result := TRUE;
      CloseHandle(tid);
    end;
  until Thread32Next(snap, TE32) = false;
  CloseHandle(snap);
end;

надеюсь, что это помогает