如何冻结程序的执行?

时间:2010-10-31 10:00:52

标签: performance delphi windows-xp

假设我有一个程序会占用处理器和/或硬盘,以至于几乎无法在该计算机上执行任何其他操作。现在我不想杀掉那个程序,因为它的作用是有用的(这是一个批处理作业,真的是CPU或磁盘很重,例如它可以压缩几千兆字节的数据文件)但是我需要做的很短的时间那台电脑上别的东西。外部程序有什么办法可以暂时冻结性能杀手?

就像旧的DOS选项一样,在不实际进行多任务处理的情况下切换程序。

假设有问题的假设程序是第三方产品,我没有源代码,也没有办法让它暂停。

我知道我可以更改程序的优先级,例如在TaskManager中,但这还不够,我想冻结它。

我说的是Windows XP作为操作系统,并且想用Delphi编写解决方案。我拥有该机器的所有权利,因此我可以以管理员身份启动,替换文件,如果有必要,我还可以安装服务。

4 个答案:

答案 0 :(得分:14)

您可以使用Process 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 );

答案 1 :(得分:6)

如果您想以编程方式执行此操作,可以使用here所述的方法。

做什么,是枚举进程中的所有线程然后暂停它们。没有SuspendProcess API,因此这是对此类调用的模拟。

请注意,这可能会产生一些不良副作用。这取决于过程及其编写方式。

我不知道在Win32 / 64 API世界中有任何其他方法。如果您降低到内核并使用NT * API,则可以使用“NtSuspendProcess”API。但这是没有记录的,所以它可以随任何版本的Windows甚至任何服务包更改(尽管不太可能)。

可以在Windows API的JEDI端口中找到“NtSuspendProcess”的声明。

答案 2 :(得分:4)

您可以使用我的ProcessInfo组件暂停属于该进程的所有线程。该方法类似于Runner向您解释的方法。代码将是这样的:

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表单here

的源代码

答案 3 :(得分: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;

希望这有帮助