假设我有一个程序会占用处理器和/或硬盘,以至于几乎无法在该计算机上执行任何其他操作。现在我不想杀掉那个程序,因为它的作用是有用的(这是一个批处理作业,真的是CPU或磁盘很重,例如它可以压缩几千兆字节的数据文件)但是我需要做的很短的时间那台电脑上别的东西。外部程序有什么办法可以暂时冻结性能杀手?
就像旧的DOS选项一样,在不实际进行多任务处理的情况下切换程序。
假设有问题的假设程序是第三方产品,我没有源代码,也没有办法让它暂停。
我知道我可以更改程序的优先级,例如在TaskManager中,但这还不够,我想冻结它。
我说的是Windows XP作为操作系统,并且想用Delphi编写解决方案。我拥有该机器的所有权利,因此我可以以管理员身份启动,替换文件,如果有必要,我还可以安装服务。
答案 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;
希望这有帮助