我希望这篇文章不是重复的。让我解释一下:
我已经考虑了类似的帖子How to pause / resume any external process under Windows?但是使用了C ++ / Python首选项,但截至发布时尚未接受答案。
我的问题:
我感兴趣的是在Delphi中可能实现了由{em> Windows Sysinternals 的 Mark Russinovich 提供的PsSuspend功能。
行情:
PsSuspend允许您暂停本地或远程系统上的进程, 这在流程消耗资源的情况下是理想的 (例如,网络,CPU或磁盘)您希望允许不同的进程 使用。而不是杀死消耗资源的进程, 暂停允许您稍后让它继续运行 时间点。
谢谢。
修改
部分实现可以。远程功能可以被删除。
答案 0 :(得分:10)
您可以尝试使用以下代码。它使用未记录的函数NtSuspendProcess
和NtResumeProcess
。我已经在Delphi 2009中构建的32位应用程序的Windows 7 64位上尝试过它,它对我有用。请注意,这些函数未记录,因此可以从Windows的未来版本中删除。
的更新强> 的
以下代码中的SuspendProcess
和ResumeProcess
包装器现在是函数,如果成功则返回True,否则返回False。
type
NTSTATUS = LongInt;
TProcFunction = function(ProcHandle: THandle): NTSTATUS; stdcall;
const
STATUS_SUCCESS = $00000000;
PROCESS_SUSPEND_RESUME = $0800;
function SuspendProcess(const PID: DWORD): Boolean;
var
LibHandle: THandle;
ProcHandle: THandle;
NtSuspendProcess: TProcFunction;
begin
Result := False;
LibHandle := SafeLoadLibrary('ntdll.dll');
if LibHandle <> 0 then
try
@NtSuspendProcess := GetProcAddress(LibHandle, 'NtSuspendProcess');
if @NtSuspendProcess <> nil then
begin
ProcHandle := OpenProcess(PROCESS_SUSPEND_RESUME, False, PID);
if ProcHandle <> 0 then
try
Result := NtSuspendProcess(ProcHandle) = STATUS_SUCCESS;
finally
CloseHandle(ProcHandle);
end;
end;
finally
FreeLibrary(LibHandle);
end;
end;
function ResumeProcess(const PID: DWORD): Boolean;
var
LibHandle: THandle;
ProcHandle: THandle;
NtResumeProcess: TProcFunction;
begin
Result := False;
LibHandle := SafeLoadLibrary('ntdll.dll');
if LibHandle <> 0 then
try
@NtResumeProcess := GetProcAddress(LibHandle, 'NtResumeProcess');
if @NtResumeProcess <> nil then
begin
ProcHandle := OpenProcess(PROCESS_SUSPEND_RESUME, False, PID);
if ProcHandle <> 0 then
try
Result := NtResumeProcess(ProcHandle) = STATUS_SUCCESS;
finally
CloseHandle(ProcHandle);
end;
end;
finally
FreeLibrary(LibHandle);
end;
end;
答案 1 :(得分:5)
Windows中没有SuspendProcess
API调用。所以你需要做的是:
SuspendThread
。ResumeThread
。答案 2 :(得分:4)
“暂停所有线程”实现存在竞争条件 - 如果您尝试挂起的程序在创建快照的时间和完成挂起的时间之间创建一个或多个线程,会发生什么?
您可以循环,获取另一个快照并暂停任何未挂起的线程,只有在您找不到时才退出。
未记录的功能避免了这个问题。
答案 3 :(得分:1)
我刚刚找到以下代码段here(作者:steve10120)。
我认为它们是有价值的,我也不能将它们作为我自己问题的替代答案发布。
恢复流程:
function ResumeProcess(ProcessID: DWORD): Boolean;
var
Snapshot,cThr: DWORD;
ThrHandle: THandle;
Thread:TThreadEntry32;
begin
Result := False;
cThr := GetCurrentThreadId;
Snapshot := CreateToolhelp32Snapshot(TH32CS_SNAPTHREAD, 0);
if Snapshot <> INVALID_HANDLE_VALUE then
begin
Thread.dwSize := SizeOf(TThreadEntry32);
if Thread32First(Snapshot, Thread) then
repeat
if (Thread.th32ThreadID <> cThr) and (Thread.th32OwnerProcessID = ProcessID) then
begin
ThrHandle := OpenThread(THREAD_ALL_ACCESS, false, Thread.th32ThreadID);
if ThrHandle = 0 then Exit;
ResumeThread(ThrHandle);
CloseHandle(ThrHandle);
end;
until not Thread32Next(Snapshot, Thread);
Result := CloseHandle(Snapshot);
end;
end;
暂停流程:
function SuspendProcess(PID:DWORD):Boolean;
var
hSnap: THandle;
THR32: THREADENTRY32;
hOpen: THandle;
begin
Result := FALSE;
hSnap := CreateToolhelp32Snapshot(TH32CS_SNAPTHREAD, 0);
if hSnap <> INVALID_HANDLE_VALUE then
begin
THR32.dwSize := SizeOf(THR32);
Thread32First(hSnap, THR32);
repeat
if THR32.th32OwnerProcessID = PID then
begin
hOpen := OpenThread($0002, FALSE, THR32.th32ThreadID);
if hOpen <> INVALID_HANDLE_VALUE then
begin
Result := TRUE;
SuspendThread(hOpen);
CloseHandle(hOpen);
end;
end;
until Thread32Next(hSnap, THR32) = FALSE;
CloseHandle(hSnap);
end;
end;
<强>声明:强>
我根本没有测试过它们。请享受,不要忘记反馈。