How do I set process priority to all child processes? Topic is solved

Get help with using AutoHotkey and its commands and hotkeys
ahkfan
Posts: 16
Joined: 14 Feb 2018, 20:01

How do I set process priority to all child processes?

12 Jul 2019, 04:02

Hello. I'm trying to run Firefox browser with high priority. The recent update disabled the option to run it in a sigle process, so now it's creating child processes.
Here is the code that I used to launch single-processed Firefox with high priority:

Code: Select all

Run "c:\Program Files (x86)\Firefox Quantum\firefox.exe" --profile "c:\Users\username\AppData\Roaming\Mozilla\Firefox\Profiles\profile1" --no-remote %gbssite% ,,,iePID
Process, Priority, %iePID%, high
So how should it be altered to affect all of Firefox's child processes?
pneumatic
Posts: 286
Joined: 05 Dec 2016, 01:51

Re: How do I set process priority to all child processes?

12 Jul 2019, 05:05

This may work for some but not all of the child processes. Use something like Process Explorer to confirm (View -> Select Columns -> Process Performance -> Base Priority. 8=Normal, 13=High).

Code: Select all

#Persistent
Run "c:\Program Files (x86)\Firefox Quantum\firefox.exe" --profile "c:\Users\username\AppData\Roaming\Mozilla\Firefox\Profiles\profile1" --no-remote %gbssite%
SetTimer , SetFirefoxPriority , 5000 
return

SetFirefoxPriority:
DetectHiddenWindows , On
WinGet , WinIDs , List , ahk_exe firefox.exe
loop %WinIDs%
{
	WinGet , ThisWinPID , PID , % "ahk_id " . WinIDs%A_Index%
	Process , Priority , %ThisWinPID% , High
	WinIDs%A_Index% := ""
}
return
The script might also need to be running as administrator
https://www.autohotkey.com/docs/commands/Run.htm#RunAs
teadrinker
Posts: 1064
Joined: 29 Mar 2015, 09:41
Contact:

Re: How do I set process priority to all child processes?

12 Jul 2019, 05:25

@pneumatic
Not all processes have windows, so I'd enumerate them like this:

Code: Select all

processName := "firefox.exe"

PIDs := EnumProcessesByName(processName)
for k, PID in PIDs
   Process, Priority, % PID, H

EnumProcessesByName(procName) {
   if !DllCall("Wtsapi32\WTSEnumerateProcesses", Ptr, 0, UInt, 0, UInt, 1, PtrP, pProcessInfo, PtrP, count)
      throw Exception("WTSEnumerateProcesses failed. A_LastError: " . A_LastError)
   
   addr := pProcessInfo, PIDs := []
   Loop % count  {
      if StrGet( NumGet(addr + 8) ) = procName
         PID := NumGet(addr + 4, "UInt"), PIDs.Push(PID)
      addr += A_PtrSize = 4 ? 16 : 24
   }
   DllCall("Wtsapi32\WTSFreeMemory", Ptr, pProcessInfo)
   Return PIDs
}
swagfag
Posts: 3068
Joined: 11 Jan 2017, 17:59

Re: How do I set process priority to all child processes?

12 Jul 2019, 05:54

Code: Select all

Run "c:\Program Files (x86)\Firefox Quantum\firefox.exe" --profile "c:\Users\username\AppData\Roaming\Mozilla\Firefox\Profiles\profile1" --no-remote %gbssite% ,,,iePID
for proc in ComObjGet("winmgmts:").ExecQuery("Select * from Win32_Process")
	if (proc.ParentProcessId = iePID)
		Process, Priority, % proc.ProcessId, high
pneumatic
Posts: 286
Joined: 05 Dec 2016, 01:51

Re: How do I set process priority to all child processes?

12 Jul 2019, 06:00

me: baby tier
teadrinker: hardcore tier
swagfag: elegant tier
teadrinker
Posts: 1064
Joined: 29 Mar 2015, 09:41
Contact:

Re: How do I set process priority to all child processes?

12 Jul 2019, 06:07

:) I prefer not to use WMI when possible, it's too slow and resource intensive.
ahkfan
Posts: 16
Joined: 14 Feb 2018, 20:01

Re: How do I set process priority to all child processes?

12 Jul 2019, 06:26

@pneumatic
Thank you, but your code only affects priority of one instance.

@swagfag
Thank you, but unfortunately it didn't affect priority at all. Maybe I should add some environment/libraries to make it work?

@teadrinker
Thank you, it works. I've added the timer to run it regulary (please let me know if it's done wrong).

Code: Select all

#Persistent

SetTimer , SetFirefoxPriority , 5000

SetFirefoxPriority:
{
processName := "firefox.exe"

PIDs := EnumProcessesByName(processName)
for k, PID in PIDs
   Process, Priority, % PID, H

EnumProcessesByName(procName) {
   if !DllCall("Wtsapi32\WTSEnumerateProcesses", Ptr, 0, UInt, 0, UInt, 1, PtrP, pProcessInfo, PtrP, count)
      throw Exception("WTSEnumerateProcesses failed. A_LastError: " . A_LastError)
   
   addr := pProcessInfo, PIDs := []
   Loop % count  {
      if StrGet( NumGet(addr + 8) ) = procName
         PID := NumGet(addr + 4, "UInt"), PIDs.Push(PID)
      addr += A_PtrSize = 4 ? 16 : 24
   }
   DllCall("Wtsapi32\WTSFreeMemory", Ptr, pProcessInfo)
   Return PIDs
}
}
But since I'm using different versions of Firefox, is it possible to track the child processes of the exact parent PID instead of all currently running firefox.exe instances? I understand that this is immodest, so if it's too time consuming, thank you anyway, your help is already substantial.
swagfag
Posts: 3068
Joined: 11 Jan 2017, 17:59

Re: How do I set process priority to all child processes?

12 Jul 2019, 07:12

win10 x64, ahk x64, ran as admin, this bit works for me:

Code: Select all

for proc in ComObjGet("winmgmts:").ExecQuery("Select * from Win32_Process")
	if (proc.ParentProcessId = theParentPID)
		Process, Priority, % proc.ProcessId, high
given a parent PID, it makes all its children High priority

the rest of the script i havent tested, maybe it has something to do with how firefox spawns its subsprocesses
teadrinker
Posts: 1064
Joined: 29 Mar 2015, 09:41
Contact:

Re: How do I set process priority to all child processes?  Topic is solved

12 Jul 2019, 09:06

For me on Windows 10 and Windows 7 this works without running as admin:

Code: Select all

#NoEnv
#Persistent
SetBatchLines, -1

Run, firefox,,, PID
timer := Func("SetChildProcessesPriority").Bind([PID], "H")
SetTimer, % timer, 5000
Return

SetChildProcessesPriority(PidArray, priority) {
   static changed := []
   for k, PID in PidArray {
      if !changed.HasKey(PID) {
         Process, Priority, % PID, % priority
         changed[PID] := ""
      }
      if (arr := EnumerateChilds(PID))
         SetChildProcessesPriority(arr, priority)
   }
}

EnumerateChilds(PID) {
   static MAX_PATH := 260
   childs := []
   hSnap := DllCall("CreateToolhelp32Snapshot", UInt, TH32CS_SNAPPROCESS := 2, UInt, 0, Ptr)
   VarSetCapacity(PROCESSENTRY32, sz := 4*7 + A_PtrSize*2 + MAX_PATH << !!A_IsUnicode, 0)
   NumPut(sz, PROCESSENTRY32, "UInt")
   DllCall("Process32First", Ptr, hSnap, Ptr, &PROCESSENTRY32)
   Loop {
      parentPID := NumGet(PROCESSENTRY32, 4*4 + A_PtrSize*2, "UInt")
      if (parentPID = PID)
         childs.Push( NumGet(PROCESSENTRY32, 4*2, "UInt") )
   } until !DllCall("Process32Next", Ptr, hSnap, Ptr, &PROCESSENTRY32)
   DllCall("CloseHandle", Ptr, hSnap)
   Return childs[1] ? childs : ""
}
ahkfan
Posts: 16
Joined: 14 Feb 2018, 20:01

Re: How do I set process priority to all child processes?

13 Jul 2019, 08:50

@teadrinker
It works like a charm, thank you so much!

@swagfag
Yes, it must be something with Firefox. Thank you for your help!

Return to “Ask For Help”

Who is online

Users browsing this forum: agrout, Bing [Bot], Google [Bot] and 213 guests