Pause a Process (windows only) in percent usage

Share your advanced PureBasic knowledge/code with the community.
User avatar
Rings
Moderator
Moderator
Posts: 1427
Joined: Sat Apr 26, 2003 1:11 am

Pause a Process (windows only) in percent usage

Post by Rings »

a console programm(you have to compile for Console) .
close it with CTRL-C, never kill it via task manager.

Usage-example:

Pureslow.exe firefox.exe 90

Code: Select all

;
;Pure Slow , slow down a process, given by Name or PID
;            from 1 to 99 %
;
; Code by S.Rings, (C) 2012
; made to the public use
; only tested on Win7-32


EnableExplicit

Define ProcessName.s 
Define I

Define Lib.i
Define PID.i
Global ProcessHandle.i
Define Result.l
Global Quit.l=0

Prototype.l Proto_NtSuspendProcess(ProcessHandle.i)
Prototype.l Proto_NtResumeProcess(ProcessHandle.i)

Global NtSuspendProcess.Proto_NtSuspendProcess
Global NtResumeProcess.Proto_NtResumeProcess

#PROCESS_ALL_ACCESS_VISTA_WIN7 = $1FFFFF

Prototype.i PFNCreateToolhelp32Snapshot(dwFlags.i, th32ProcessID.i) ;
Prototype.b PFNProcess32First(hSnapshot.i, *lppe.PROCESSENTRY32) ;
Prototype.b PFNProcess32Next(hSnapshot.i, *lppe.PROCESSENTRY32) ;


OpenConsole()


Procedure GetPidByName(p_name$)
    Protected hDLL.i, process_name$
    Protected PEntry.PROCESSENTRY32, hTool32.i
    Protected pCreateToolhelp32Snapshot.PFNCreateToolhelp32Snapshot
    Protected pProcess32First.PFNProcess32First
    Protected pProcess32Next.PFNProcess32Next
    Protected pid.i
   
    hDLL = OpenLibrary(#PB_Any,"kernel32.dll")
   
    If hDLL
        pCreateToolhelp32Snapshot = GetFunction(hDLL,"CreateToolhelp32Snapshot")
        pProcess32First = GetFunction(hDLL,"Process32First")
        pProcess32Next = GetFunction(hDLL,"Process32Next")
    Else
        ProcedureReturn 0
    EndIf
   
    PEntry\dwSize = SizeOf(PROCESSENTRY32)
    hTool32 = pCreateToolhelp32Snapshot(#TH32CS_SNAPPROCESS, 0)
    pProcess32First(hTool32, @PEntry)
    process_name$ = Space(#MAX_PATH)
    CopyMemory(@PEntry\szExeFile,@process_name$,#MAX_PATH)
   
    If  UCase(process_name$) = UCase(p_name$)
        ProcedureReturn PEntry\th32ProcessID
    EndIf
   
    While pProcess32Next(hTool32, @PEntry) > 0
        process_name$ = Space(#MAX_PATH)
        CopyMemory(@PEntry\szExeFile,@process_name$,#MAX_PATH)
       
        If  UCase(process_name$) = UCase(p_name$)
            ProcedureReturn PEntry\th32ProcessID
        EndIf
   
    Wend
   
    CloseLibrary(hDLL)
   
    ProcedureReturn 0
EndProcedure

Lib=OpenLibrary(#PB_Any,"ntdll.dll")
If Lib
  NtSuspendProcess.Proto_NtSuspendProcess = GetFunction(Lib, "NtSuspendProcess")
  NtResumeProcess.Proto_NtResumeProcess   = GetFunction(Lib, "NtResumeProcess")
Else
  PrintN( "cannot open dll")
  End  
EndIf  


Procedure.b Cons(dwCtrlType.l)
  Static Result.l
  ;If dwCtrlType = #CTRL_CLOSE_EVENT
  Quit=1
  Result=NtResumeProcess(ProcessHandle)
  Define i
  For I=1 To 10
   Beep_(100+(I*9),20)
  Next 
  
  ProcedureReturn 1
   
EndProcedure

SetConsoleCtrlHandler_(@Cons(),#True) ;add handler

Define WaitPercent.l=50 ;default is 50%

Define CP.l=CountProgramParameters() 
If cp<1 Or Cp>2
  PrintN ("   Usage: PureSlow ExeName.exe PercentageWait(1-99)")
  PrintN ("example = Pureslow.exe Firefox.exe 80")
  End
EndIf  
If CP=1 
  WaitPercent=50
EndIf
If cp=2
  ProcessName=ProgramParameter(0)
  WaitPercent=Val( ProgramParameter(1))
EndIf  

;check for valid values
If WaitPercent<1 
  WaitPercent=1
EndIf
If WaitPercent>100
  WaitPercent=100
EndIf

Define OPercent.l=Waitpercent
Define Time_RUN.i  
Define Time_Wait.i 

;can we use lower sleepings ?

If Mod(Waitpercent , 10)=0
 Waitpercent=Waitpercent/10 
 Time_RUN=(10-Waitpercent)
 Time_Wait=(Waitpercent)
Else
 Time_RUN=(100-Waitpercent)
 Time_Wait=(Waitpercent)
EndIf


If Val(ProcessName)=0 
 PID=GetPidByName(ProcessName);find the PID
Else
  ;the PID is given
  PID=Val(ProcessName)
EndIf  
 
If PID=0
  PrintN ( "PID of " + ProcessName +" Not found")
  End
EndIf  


If OSVersion()<#PB_OS_Windows_XP
  PrintN ("not supported OS")
EndIf  
If OSVersion()>#PB_OS_Windows_XP
  ProcessHandle = OpenProcess_(#PROCESS_ALL_ACCESS_VISTA_WIN7,#False,PID)
Else
  ProcessHandle= OpenProcess_(#PROCESS_ALL_ACCESS,#False,PID)
EndIf
If ProcessHandle=0 
  PrintN ("cannot open PID...")
  End
EndIf  
PrintN ("________________________________________________________")

PrintN ("Pure Slow 1.0 , (c) 2012 by S.Rings     " +Str(Time_RUN)+"/"+Str(Time_Wait))
PrintN ("________________________________________________________")
PrintN("Slowing down " +  ProcessName + " " +Str(OPercent)+"% , "+ Str(100-OPercent)+"% Runtime")

For I=1 To 10
 Beep_(1000-(I*9),20)
Next 


Repeat
    
 
    ;Debug "suspending pid "+Str(pid)
    Result=NtSuspendProcess(ProcessHandle)
    Delay(Time_wait)
    Result=NtResumeProcess(ProcessHandle)
    Delay(Time_RUN)
    
    
Until Quit = 1
  

Result=NtResumeProcess(ProcessHandle)
CloseHandle_(ProcessHandle)
For I=1 To 10
 Beep_(100+(I*9),20)
Next 
End  
SPAMINATOR NR.1
DarkDragon
Addict
Addict
Posts: 2228
Joined: Mon Jun 02, 2003 9:16 am
Location: Germany
Contact:

Re: Pause a Process (windows only) in percent usage

Post by DarkDragon »

Hmm what's the result I should get? Chrome still loads webpages as fast as before when using "PureSlow.exe chrome.exe 80" as command line. And which instance of the target process will be slower at the end?
bye,
Daniel
Thorium
Addict
Addict
Posts: 1271
Joined: Sat Aug 15, 2009 6:59 pm

Re: Pause a Process (windows only) in percent usage

Post by Thorium »

I tried something like that a while ago. Never got it to work very well. Because windows will boost the priority if the thread resumes, so negating the delay. You get it slower but you cant accuratly control the speed of the thread. At least i didnt got it working accuratly.
Post Reply