Why pause and resume processes?
Anyone using the Windows NT product line (Windows 2000 and Windows XP) must have
used the task manager utility. This utility, activated by pressing
CTRL+SHIFT+ESC, brings up a list of the active processes and allows you several
actions for controlling them: starting new processes, stopping processes and
setting their priority. When you have some process that is taking a lot of
resources (normally CPU time), you can easily assign it the lowest priority and
the system will take care of assigning only the remaining resources or the
"idle time" on the machine.
Well, a feature I always missed from Windows and present on other operating
systems is the ability of pausing and resuming a process. Some daily situations
you could face where this feature would be useful (actually, the ones I use it
for):
-
You have a time-consuming operation, e.g. a big build, and want to pause it for
doing something quickly and resuming it after doing this
-
You have some P2P software or download running and want to pause and resume it
without reconnecting and want to browse some pages quickly
-
A program starts a disk trashing operation and you want to send and e-mail
-
A program starts working in a way it shouldn't for just a moment and you want
to attach a debugger to it
-
You have a buggy process running and want to kill it fast
How it is done
The main problem is: there is no SuspendProcess
API function. And
there is no documented or safe way of doing this.
The only simple way of doing this is via SuspendThread
/ResumeThread
.
This pair of API functions allows you to suspend and resume a thread. More than
that, for the sake of safety, they maintain an internal "suspend count'. Each
time you call SuspendThread
, it increments this counter. ResumeThread
,
on the other hand, decreases this counter. If this was not done this way, the
caller of SuspendThread
would have no way of knowing how to
restore the original state of the thread. Calling ResumeThread
after
calling SuspendThread
effectively restores the original thread's
state.
Knowing this, it is very straightforward suspending a process: it is just a
matter of listing all the threads on a process, opening a handle for each of
them and calling SuspendThread
. The resuming is done the same way.
The ToolHelp32 API has functions for easily listing threads and processes on a
system. Actually, there are two functions that do this on my code that were
shamelessly borrowed from MSDN samples.
So, I wrote this little command line utility (I have an idea for integrating it
with the task manager, but I have not the time for doing it right now).
How to use it
I suggest you to put the executable anywhere on the PATH. The Windows directory
would be fine. Always compile this program without DLL dependencies on the CRT,
so the program will start faster. You could be starting this program under very
adverse conditions, so looking for a MSVCRT*.DLL and loading it could make a
huge difference in the startup time.
As with most command line tools, it is meant to be used from
the command prompt, by clicking on the "Command Prompt" shortcut or opening Start/Run and
executing cmd.exe. The usage for the program is very simple:
pausep PID [/r]
If you type only pausep
without arguments, the program will display
its usage and a list of running processes and their PID. If you type pausep PID
, the program will call SuspendThread
on all the
process's threads. This will suspend the threads or increment their suspend
count. If you pass the "/r"
argument, the program will do the
opposite action, i.e., resuming the thread. Note that if you pausep
the same process 3 times without resuming, you will need to use pausep /r
it for 3 times too.
The risks with this approach
Not all programs are well written. Not all programs are made to be suspended,
specially the multithreaded ones. Programs that implement timeouts may behave
abnormally if you pause and resume them. When you pause and resume threads in an
arbitrary order, like with this utility, you can create deadlocks.
So, only use this program when you know what you are doing.
The standard disclaimer
As I said before, this is not the safest tool in the world. Use it at your own
risk: if you use it, you can loose data, profit, have hardware problems, cause
radioactive contamination and start a world war. But, for me, it works fine and
never had a problem.
Well, the code in this article is free for you to use any way you want. If you
improve it, drop me a note, so I can keep the code in sync. If you make money
with this code, you are a genius! You deserve the money. Just remember to send
me a "thank you" and give me some tips. I will not reject any money you send me
too.