Jump to content
The Kandie Man

Process Suspend/Process Resume UDF

Recommended Posts

MrChiliCheese

Hey, is there a way to get the information if a process is suspended?

Share this post


Link to post
Share on other sites
vimbat

What function would you use to turn off the sound for a process?

Share this post


Link to post
Share on other sites
AdmiralAlkex

What function would you use to turn off the sound for a process?

That's not possible unless it's something lika a media player that supports some sort of "remote control" (COM, dll, window msg etc)

Share this post


Link to post
Share on other sites
jvanegmond

That's not possible unless it's something lika a media player that supports some sort of "remote control" (COM, dll, window msg etc)

You can set volume for a program in Vista, but I'm not sure what function you should call for that.

Share this post


Link to post
Share on other sites
JellyFish666

I have been looking for something like this for a long time now, this should be added to new versions of Autoit for sure it is handy.

Share this post


Link to post
Share on other sites
therks

These funcs never did get added. Maybe someone should take a crack at rewriting them to UDF standards. Seems like they'd be useful to several people...

Share this post


Link to post
Share on other sites
SmOke_N

maybe you can use these to pause sound:

http://msdn.microsoft.com/en-us/library/ms712675(VS.85).aspx

they are not functions, though.. they are macros so I don't know how to use them

Those use MCI so why wouldn't this work?

http://www.autoitscript.com/forum/index.ph...3972&hl=MCI


Common sense plays a role in the basics of understanding AutoIt... If you're lacking in that, do us all a favor, and step away from the computer.

Share this post


Link to post
Share on other sites
cypher175

Well which one works better..?? The Kandie Man's or SmOke_N's..??

is either one of their scripts able to check the state of the process before it suspends or resumes it..??

and what if the process that needs to be suspended/resumed has the same name as an already existing running process.. how would you be able to determine the exact PID or process location to specify for suspending/resuming..??

Share this post


Link to post
Share on other sites
tom13

Func _ProcessSuspend($hProcess)
    Local $aSuspend = DllCall("ntdll.dll","int","NtSuspendProcess","int",$hProcess)
    If IsArray($aSuspend) Then Return 1
    SetError(1)
    Return 0
EndFunc

Func _ProcessResume($hProcess)
    Local $aResume = DllCall("ntdll.dll","int","NtResumeProcess","int",$hProcess)
    If IsArray($aResume) Then Return 1
    SetError(1)
    Return 0
EndFunc

Share this post


Link to post
Share on other sites
SaulMageste

Im new to all this AutoIt world. Would anyone mind making a full example on how would it bee if I wanted to suspend Notepad.exe and a button to resume it too. Please?

Share this post


Link to post
Share on other sites
jvanegmond

Im new to all this AutoIt world. Would anyone mind making a full example on how would it bee if I wanted to suspend Notepad.exe and a button to resume it too. Please?

Bit old but should help

#Region
#AutoIt3Wrapper_icon=favicon.ico
#AutoIt3Wrapper_outfile=processfreezer.exe
#endregion

#include <WindowsConstants.au3>
#include <EditConstants.au3>
#include <StaticConstants.au3>
#include <GUIConstantsEx.au3>
#include <IE.au3>

$oIE = _IECreateEmbedded()

$FORM1 = GUICreate("Process Freezer", 255, 170)
$BUTTON1 = GUICtrlCreateButton("Freeze Process (Ctrl + Shift + D)", 8, 55, 240, 25)
$INPUT1 = GUICtrlCreateInput("notepad.exe", 80, 5, 169, 21)
GUICtrlCreateLabel("Process:", 5, 10, 45, 17)
GUICtrlCreateLabel("Auto Unfreeze", 5, 35, 72, 17)
$INPUT2 = GUICtrlCreateInput("7", 80, 30, 169, 21, $ES_NUMBER)
;$LABEL1 = GUICtrlCreateLabel("www.manadar.com", 5, 85, 243, 21, $ES_CENTER, $WS_EX_CLIENTEDGE)

GUICtrlSetColor(-1, 221)
GUICtrlSetFont(-1, 10, 800)
GUISetState(@SW_SHOW)

HotKeySet("^+D", "_MToggle")

Dim $TOGGLE = True, $PROCESS, $TIMER = 0, $INITTIMER = 0
While 1
    $NMSG = GUIGetMsg()
    Switch $NMSG
        Case $GUI_EVENT_CLOSE
            Exit
        Case $BUTTON1
            _MTOGGLE()
        ;Case $LABEL1
        ;   ShellExecute("http://www.manadar.com")
    EndSwitch
WEnd

Func _MTOGGLE()
    If $TOGGLE Then
        $PROCESS = GUICtrlRead($INPUT1)
        $TIMER = GUICtrlRead($INPUT2)
        $INITTIMER = $TIMER
        If $TIMER > 0 Then
            AdlibRegister("_MTimer", 1000)
        EndIf
        _MPROCESSSUSPEND($PROCESS)
        $TOGGLE = False
        GUICtrlSetState($INPUT1, $GUI_DISABLE)
        GUICtrlSetState($INPUT2, $GUI_DISABLE)
        GUICtrlSetData($BUTTON1, "Unfreeze Process")
    Else
        _MPROCESSRESUME($PROCESS)
        $TOGGLE = True
        AdlibUnRegister("_MTimer")
        GUICtrlSetState($INPUT1, $GUI_ENABLE)
        GUICtrlSetState($INPUT2, $GUI_ENABLE)
        GUICtrlSetData($BUTTON1, "Freeze Process")
        GUICtrlSetData($INPUT2, $INITTIMER)
    EndIf
EndFunc


Func _MTIMER()
    $TIMER = $TIMER - 1
    GUICtrlSetData($INPUT2, $TIMER)
    If $TIMER <= 0 Then
        _MTOGGLE()
    EndIf
EndFunc


Func _MPROCESSSUSPEND($SPROCESSNAME)
    $SPROCESSPID = ProcessExists($SPROCESSNAME)
    If $SPROCESSPID Then
        $AI_HANDLE = DllCall("kernel32.dll", "int", "OpenProcess", "int", 2035711, "int", False, "int", $SPROCESSPID)
        $I_SUCESS = DllCall("ntdll.dll", "int", "NtSuspendProcess", "int", $AI_HANDLE[0])
        DllCall("kernel32.dll", "ptr", "CloseHandle", "ptr", $AI_HANDLE)
        If IsArray($I_SUCESS) Then
            Return 1
        Else
            SetError(1)
            Return 0
        EndIf
    Else
        SetError(2)
        Return 0
    EndIf
EndFunc


Func _MPROCESSRESUME($RPROCESSNAME)
    $RPROCESSPID = ProcessExists($RPROCESSNAME)
    If $RPROCESSPID Then
        $AI_HANDLE = DllCall("kernel32.dll", "int", "OpenProcess", "int", 2035711, "int", False, "int", $RPROCESSPID)
        $I_SUCESS = DllCall("ntdll.dll", "int", "NtResumeProcess", "int", $AI_HANDLE[0])
        DllCall("kernel32.dll", "ptr", "CloseHandle", "ptr", $AI_HANDLE)
        If IsArray($I_SUCESS) Then
            Return 1
        Else
            SetError(1)
            Return 0
        EndIf
    Else
        SetError(2)
        Return 0
    EndIf
EndFunc
Edited by Manadar

Share this post


Link to post
Share on other sites
firsttimer

Can someone show me an example of how to query a notepad.exe whether its suspended or not, please?

I need it.

Thank you.

Edited by firsttimer

Share this post


Link to post
Share on other sites
Chance

Can someone show me an example of how to query a notepad.exe whether its suspended or not, please?

I need it.

Thank you.

Share this post


Link to post
Share on other sites
Robinson1

#1 First of all please note that all the example above doesn't close the opened handle to the process.

That'll be correctly:
DllCall('kernel32.dll', 'ptr','CloseHandle', 'ptr',$ai_Handle[0])

#2 Second thing NtSuspendProcess and NtResumeProcess are undocumented functions - means that microsoft doesn't have them in their Win32-API documentation - >More[https://social.msdn.microsoft.com/forums/windowsdesktop/en-us/b5c5121c-bf48-47bd-b612-e2f61c5e5d82/ntsuspendprocess]

A more 'official' way would be to use DebugActiveProcess(PID) + DebugSetProcessKillOnExit(0) and DebugActiveProcessStop(PID) to suspend or resume a process.
See ->_ProcessSuspendResume2 in the following example (you'll maybe need to scroll down a little ) on how it's being used.

#3 The direct use of literals like this   

... 'OpenProcess', 'int', 0x1f0fff, ...

is really ugly sloppy coding style - use constants or even better include them. Like this:

#include <ProcessConstants.au3>
... 'OpenProcess', 'int', $PROCESS_ALL_ACCESS , ...

it'll be much better readable.

Okay now here it is a small usefull app to'll bring back the 'pause' key from the dos era into Windows.
Pressing PAUSE will suspend the current active process(<= the currently active windows is running in )
Pressing PAUSE again will resume it.

#include <WinAPI.au3>
#include <ProcessConstants.au3>

Func _ProcessSuspendResume($iPIDorName, $iSuspend = True)

   If IsString($iPIDorName) Then $iPIDorName = ProcessExists($iPIDorName)
   If Not $iPIDorName Then Return SetError(2, 0, 0)

   ; Consider using $PROCESS_SUSPEND_RESUME = 0x00000800 instead of $PROCESS_ALL_ACCESS
   Local $ai_Handle = _WinAPI_OpenProcess( $PROCESS_ALL_ACCESS, False, $iPIDorName )
   ;Local $ai_Handle = DllCall("kernel32.dll", 'int','OpenProcess', 'int', 0x1f0fff, 'int',False, 'int',$iPIDorName)[0]

   ; Note: "NtSuspendProcess" is an undocumented API
   Local $i_sucess = DllCall("ntdll.dll","int","Nt" & ($iSuspend ? "Suspend" : "Resume") & "Process" _
                                                ,"int",$ai_Handle)

   _WinAPI_CloseHandle($ai_Handle)
   ;DllCall('kernel32.dll', 'ptr','CloseHandle', 'ptr',$ai_Handle)

   If IsArray($i_sucess) Then Return 1
   Return SetError(1, 0, 0)
EndFunc  ;==>_ProcessSuspendResume <-based on: http://autoitscript.com/forum/topic/32975-process-suspendprocess-resume-udf/


Func TogglePause()
   $g_bPaused = Not $g_bPaused

;~    $PIDorName = $TARGET_PROCESSNAME
   $PIDorName = WinGetProcess("[ACTIVE]")

    _ProcessSuspendResume($PIDorName, $g_bPaused)

EndFunc   ;==>TogglePause

; The more 'offical' & easy way (http://stackoverflow.com/a/11010508/3135511)
Func _ProcessSuspendResume2($iPIDorName, $iSuspend = True)


   If IsString($iPIDorName) Then $iPIDorName = ProcessExists($iPIDorName)
   If Not $iPIDorName Then Return SetError(2, 0, 0)

   if $iSuspend then
      ;Note Opens Process with PROCESS_ALL_ACCESS
      DllCall('kernel32.dll','ptr','DebugActiveProcess','int',$iPIDorName)

      ; you may leave out DebugSetProcessKillOnExit; however then your supended App will also Exit when you quit this AutoIt App
      DllCall('kernel32.dll','ptr','DebugSetProcessKillOnExit','int',False)
   Else
      DllCall('kernel32.dll','ptr','DebugActiveProcessStop','int',$iPIDorName)
   EndIf

EndFunc

;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Global Const $APP_NAME = "Pause for Windows"
Global Const $TARGET_PROCESSNAME = "Kingdom Rush.exe"

; Base on the 'HotKeySet' sample from the AutoIt help
; Press Esc to terminate script, Pause/Break to "pause"

Global $g_bPaused = False

HotKeySet("{PAUSE}", "TogglePause")
HotKeySet("{ESC}", "Terminate")
HotKeySet("+!h", "ShowMessage") ; Shift-Alt-h

While 1
    Sleep(100)
WEnd

Func Terminate()
    Exit
EndFunc   ;==>Terminate

Func ShowMessage()
     MsgBox($MB_SYSTEMMODAL, APP_NAME & " - Help", "Press the >Pause< Key to your keyboard to suspend the current Process" & @CRLF & _
                                 "(= the one whose windows is active)." & @CRLF & _
                                 "Press >Pause< again to resume it.")
EndFunc   ;==>ShowMessage

^-Really neat for games like Kingdom rush that doesn't have a pause function (or like this one the pause hides too much of the gaming screen)
or image you've a cpu intensive app like a packer that doesn't have a 'Pause' Key.

Limitiations of code above:

* Does take care for the case that you might change to another process
* Alt+shift+h gives an error to fix move the '
Global Const $APP_NAME' just to the beginning
Man what a stupid limitation why global's can be a the end or between functions?

Anyway In the attached file I already fixed this (But for the post this gets somehow much overhead - since the focus should be here on supend/resume a process)

_________________________________________________________________________________

Offtopic

And one other thing I noticed it's about the Ternary-operator like this:

"Nt" & ($iSuspend ? "Suspend" : "Resume")

in the current AutoIT Help file it is not missing in the section that 'talks' about operator precedence.(autoit.chm::/html/intro/lang_operators.htm)

 

PauseForWindows.au3

Edited by Robinson1
  • Like 1

Share this post


Link to post
Share on other sites
gil900

Is there a API for hibernate a Process ?

someone asked it here:

http://stackoverflow.com/questions/7938318/hibernate-an-entire-process-in-windows

 According to what people are saying this is not possible in windows but I hope I am wrong

Edited by gil900

Share this post


Link to post
Share on other sites
Robinson1

Is there a API for hibernate a Process ?

Interesting question - but no there is definitely no such a thing like an API for hibernate a Process.
(suprisingly Windows don't officially offers an API to suspend/resume a process)

I once tried something when unpacking  / dumping some process. With
Read/WriteProcessMemory you can access the Memory of some other process. CreateRemoteThread may be used to start/create some other thread in another process. But beside the memory there are objects like for ex windows, files-handles, reg-handles, signaling stuff mutex's/semaphor's... you may also take care for and not to forget driver handles(of graphic or sound).
Well unpacking is dealing just with dumping memory stuff and the more or less initialed API-imports - you don't deal with the rest.

To create something to hibernate a Process can be a big undertake.

But well maybe it's good to see how suspend / resume to RAM is done in detail to get some inspiration.
Or that crashdump file *.dmp that contains the cpu state+stack of all threads 

 

Edited by Robinson1

Share this post


Link to post
Share on other sites
reb

I found this  This.

It certainly puts win 8.1 in hibernate but does not restore it after the time set with this.  SetWakeUpTime(@HOUR,@min+1); wakeup the system in 2 minutes from now

Start button wakes up just fine.


MEASURE TWICE - CUT ONCE

Share this post


Link to post
Share on other sites
gil900

Anyway thank you for this API. this is very usefull
Sometimes I'm not fast enough to read subtitles in games and this really solves my problem and magicaly works perfectly!

 

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

×