Page 1 of 1
How to suspend a process?
Posted: Thu Feb 06, 2014 6:51 pm
by ostapas
Good day,
need to suspend/resume a process. To my astonishment, could not find any PB examples, but found these 2 functions on AutoIt forums:
Code: Select all
Func ProcessSuspend($Process_PID)
$ai_Handle = DllCall("kernel32.dll", 'int', 'OpenProcess', 'int', 0x1f0fff, 'int', False, 'int', $Process_PID)
$i_sucess = DllCall("ntdll.dll", "int", "NtSuspendProcess", "int", $ai_Handle[0])
DllCall('kernel32.dll', 'ptr', 'CloseHandle', 'ptr', $ai_Handle)
EndFunc
Func ProcessResume($Process_PID)
$ai_Handle = DllCall("kernel32.dll", 'int', 'OpenProcess', 'int', 0x1f0fff, 'int', False, 'int', $Process_PID)
$i_sucess = DllCall("ntdll.dll", "int", "NtResumeProcess", "int", $ai_Handle[0])
DllCall('kernel32.dll', 'ptr', 'CloseHandle', 'ptr', $ai_Handle)
EndFunc
Maybe someone who has winapi knowledge and a spare minute could help to transform this to PB?

Re: How to suspend a process?
Posted: Thu Feb 06, 2014 8:16 pm
by JHPJHP
Try the following:
- can also be done with threads:
http://stackoverflow.com/questions/1101 ... in-windows
- may not need [ AdjustCurrentProcessPrivilege ], but I included it just in case
Windows Services & Other Stuff\Other_Stuff\ProcessStuff\SuspendProcess.pb
Re: How to suspend a process?
Posted: Thu Feb 06, 2014 9:03 pm
by ostapas
Working fine, many thanks!
Re: How to suspend a process?
Posted: Fri Feb 07, 2014 2:59 am
by PB
> may not need [ AdjustCurrentProcessPrivilege ]
I don't think it does. I run under a Limited account (not Admin) and your
code paused and resumed every process that I tested it with. Good job.
Re: How to suspend a process?
Posted: Fri Feb 07, 2014 9:25 am
by ostapas
JHPJHP, thanks again for arranging the code into procedures
Re: How to suspend a process?
Posted: Wed Nov 19, 2014 12:40 pm
by smacker
NtSuspendProcess is an undocumented function isn't it? Undocumented functions are not supported in the API, and may suddenly vanish or be changed in some way by later updates/service packs or versions of windows, so I'm a little shy about using such if I want my stuff to keep working in later versions of Windows or after updates/service packs in case something does happen to NtSuspendProcess.
This is something I used in Windows 7 64 bit (don't know about Win 7 32 bit version) for my purposes to pause (suspend) the thread of another process via its PID that did not belong to my own process which is the same thing as pausing/suspending the process, you could also do your own process as well, never tried it in Windows 8 so don't know about there but it worked in Windows 7 64 bit, the not so pretty version is this:
Code: Select all
Structure thread32
size.l
use.l
idth.l
parentid.l
base.l
delta.l
flags.l
EndStructure
OpenLibrary(0,"kernel32.dll")
Procedure pause(pid)
thread.thread32
snap = CallFunction(0, "CreateToolhelp32Snapshot",4,0)
If snap
thread\size=SizeOf(thread32)
CallFunction(0,"Thread32First",snap,@thread)
If thread\parentid=pid
h=CallFunction(0,"OpenThread",2,0,thread\idth)
SuspendThread_(h)
CloseHandle_(h)
EndIf
While CallFunction(0,"Thread32Next",snap,@thread)
If thread\parentid=pid
h=CallFunction(0,"OpenThread",2,0,thread\idth)
SuspendThread_(h)
CloseHandle_(h)
EndIf
Wend
EndIf
EndProcedure
Procedure resume(pid)
thread.thread32
snap = CallFunction (0, "CreateToolhelp32Snapshot",4,0)
If snap
thread\size=SizeOf(thread32)
CallFunction(0,"Thread32First",snap,@thread)
If thread\parentid=pid
h=CallFunction(0,"OpenThread",2,0,thread\idth)
ResumeThread_(h)
CloseHandle_(h)
EndIf
While CallFunction(0,"Thread32Next",snap,@thread)
If thread\parentid=pid
h=CallFunction(0,"OpenThread",2,0,thread\idth)
ResumeThread_(h)
CloseHandle_(h)
EndIf
Wend
EndIf
EndProcedure
Can't find the pretty version right now but I'm sure you could restructure the code some to pretty it up a little.
Re: How to suspend a process?
Posted: Wed Nov 19, 2014 12:43 pm
by ostapas
Smacker, many thanks!
Re: How to suspend a process?
Posted: Wed Nov 19, 2014 2:47 pm
by Thunder93
smacker raises some valid points.
Code: Select all
Prototype protoOpenThread(dwDesiredAccess.l, bInheritHandle.b, dwThreadId.l)
Global OpenThread.protoOpenThread
Procedure ResumeProcess(ProcessID.l)
Define.l hSnap, cThr, IsRes
ThrHandle.i
LibKernel32 = OpenLibrary(#PB_Any,"Kernel32.dll")
If Not LibKernel32 : ProcedureReturn 0 : EndIf
OpenThread = GetFunction(LibKernel32, "OpenThread")
Thread.THREADENTRY32
cThr = GetCurrentThreadId_()
hSnap = CreateToolhelp32Snapshot_(#TH32CS_SNAPTHREAD, 0)
If hSnap <> #INVALID_HANDLE_VALUE
Thread\dwSize = SizeOf(THREADENTRY32)
If Thread32First_(hSnap, Thread)
Repeat
If (Thread\th32ThreadID <> cThr) And (Thread\th32OwnerProcessID = ProcessID)
ThrHandle = OpenThread(#THREAD_SUSPEND_RESUME, 0, Thread\th32ThreadID)
If ThrHandle = 0 : Break : EndIf
IsRes = ResumeThread_(ThrHandle)
CloseHandle_(ThrHandle)
EndIf
Until Not Thread32Next_(hSnap, Thread)
CloseHandle_(hSnap)
CloseLibrary(LibKernel32)
If IsRes > 0 : ProcedureReturn 1 : EndIf
EndIf
EndIf
EndProcedure
Procedure SuspendProcess(PID.l)
Define.l hSnap, IsSus
ThrHandle.i
LibKernel32 = OpenLibrary(#PB_Any,"Kernel32.dll")
If Not LibKernel32 : ProcedureReturn 0 : EndIf
OpenThread = GetFunction(LibKernel32, "OpenThread")
THR32.THREADENTRY32
hSnap = CreateToolhelp32Snapshot_(#TH32CS_SNAPTHREAD, 0)
If hSnap <> #INVALID_HANDLE_VALUE
THR32\dwSize = SizeOf(THR32)
Thread32First_(hSnap, THR32)
Repeat
If THR32\th32OwnerProcessID = PID
LibKernel32 = OpenLibrary(#PB_Any,"Kernel32.dll")
ThrHandle = OpenThread(#THREAD_SUSPEND_RESUME, #False, THR32\th32ThreadID)
If ThrHandle <> #INVALID_HANDLE_VALUE
IsSus = SuspendThread_(ThrHandle)
CloseHandle_(ThrHandle)
EndIf
EndIf
Until Thread32Next_(hSnap, THR32) = #False
CloseHandle_(hSnap)
CloseLibrary(LibKernel32)
If IsSus <> #INVALID_HANDLE_VALUE : ProcedureReturn 1 : EndIf
EndIf
EndProcedure
Re: How to suspend a process?
Posted: Thu Mar 18, 2021 7:13 pm
by BarryG
Apparently this pausing/resuming with the techniques above is bad/wrong because it doesn't pause
all threads of a process, which is required. The answer is to use DebugActiveProcess_(pid) to pause and DebugActiveProcessStop_(pid) to resume, because this is how debuggers do it to ensure all threads of a PID are suspended. However, DebugActiveProcessStop_() doesn't exist in PureBasic. How can we add it? I tried this, but it doesn't work:
Code: Select all
Procedure DebugActiveProcessStop(pid)
If OpenLibrary(0,"kernel32.dll")
CallFunction(0,"DebugActiveProcessStop",0,0,pid)
CloseLibrary(0)
EndIf
EndProcedure
pid=11392 ; Change to an observable running process ID.
DebugActiveProcess_(pid)
Sleep_(1000)
DebugActiveProcessStop(pid)
Re: How to suspend a process?
Posted: Thu Mar 18, 2021 11:10 pm
by breeze4me
BarryG wrote:Apparently this pausing/resuming with the techniques above is bad/wrong because it doesn't pause
all threads of a process, which is required. The answer is to use DebugActiveProcess_(pid) to pause and DebugActiveProcessStop_(pid) to resume, because this is how debuggers do it to ensure all threads of a PID are suspended. However, DebugActiveProcessStop_() doesn't exist in PureBasic. How can we add it? I tried this, but it doesn't work:
Code: Select all
Procedure DebugActiveProcessStop(pid)
If OpenLibrary(0,"kernel32.dll")
CallFunction(0,"DebugActiveProcessStop",0,0,pid)
CloseLibrary(0)
EndIf
EndProcedure
pid=11392 ; Change to an observable running process ID.
DebugActiveProcess_(pid)
Sleep_(1000)
DebugActiveProcessStop(pid)
1. The parameters are wrong.
2. It does not seem to apply to 64-bit processes if it is compiled with PB x86. Compile it with PB x64 and check it out again.
Code: Select all
CompilerIf #PB_Compiler_Processor = #PB_Processor_x86
CompilerError "Use PB x64."
CompilerEndIf
Procedure DebugActiveProcessStop(pid)
If OpenLibrary(0,"kernel32.dll")
CallFunction(0,"DebugActiveProcessStop",pid)
CloseLibrary(0)
EndIf
EndProcedure
pid=11392 ; Change to an observable running process ID.
r = DebugActiveProcess_(pid)
If r
Sleep_(1000)
Debug DebugActiveProcessStop(pid)
EndIf
Re: How to suspend a process?
Posted: Thu Mar 18, 2021 11:25 pm
by BarryG
Thanks, breeze4me. And you're right: compiling as 32-bit works great for 32-bit processes, but can't pause 64-bit.