Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Suspend/resume processes as PsSuspend does

I hope this post is not a duplicate one. Let me explain:

I have considered the similar post How to pause / resume any external process under Windows? but with C++/Python preference and yet without an accepted answer as of the time of posting.


My Question:

I'm interested in a possible implementation in Delphi of the functionality provided by PsSuspend by Mark Russinovich of Windows Sysinternals.

Quotes:

PsSuspend lets you suspend processes on the local or a remote system, which is desirable in cases where a process is consuming a resource (e.g. network, CPU or disk) that you want to allow different processes to use. Rather than kill the process that's consuming the resource, suspending permits you to let it continue operation at some later point in time.

Thank you.


Edit:

A partial implementation will do. Remote capability can be dropped.

like image 610
menjaraz Avatar asked Apr 14 '12 11:04

menjaraz


People also ask

How do you suspend a resume?

Suspending processes then reactivating them can work or not, depending on how the process responds to the suspension. Probably the only surefire way to fix these errors would be to reboot. Try rebooting, then see if the processes are working again.

What does it mean to suspend a process?

A suspended process is one that is turned off. The process exists but it does not get scheduled for execution. For example, suppose you have a server that you want to run a CPU-intensive molecular modeling program that will take two months to finish running.

What happens when you suspend a process?

What is the Suspended Process? Ans: Suspended Process are those process which has been turned off temporarily. When a process is temporarily suspended then later on it will restart from exactly the same state where it was stopped. So, the state of those processes must be stored somewhere else on your PC.

How do I suspend a resume in Linux?

You may be familiar with suspending a process that is running in the foreground by pressing CTRL-Z. It will suspend the process, until you type "fg", and the process will resume again.


2 Answers

You can try to use the following code. It uses the undocumented functions NtSuspendProcess and NtResumeProcess. I've tried it on Windows 7 64-bit from the 32-bit application built in Delphi 2009 and it works for me. Note that these functions are undocumented thus can be removed from future versions of Windows.

Update

The SuspendProcess and ResumeProcess wrappers from the following code are now functions and returns True if succeed, False otherwise.

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;
like image 88
TLama Avatar answered Sep 28 '22 20:09

TLama


There is no SuspendProcess API call in Windows. So what you need to do is:

  1. Enumerate all the threads in the process. See RRUZ's answer for sample code.
  2. Call SuspendThread for each of these threads.
  3. In order to implement the resume part of the program, call ResumeThread for each thread.
like image 41
David Heffernan Avatar answered Sep 28 '22 20:09

David Heffernan