Albuquerquefx Posted December 11, 2007 Posted December 11, 2007 I assume I can't post in that particular section of the forum because I'm a n00b (ha!) so I'm gonna post it here and hope that a mod can drop-kick it where it belongs. I did a bit of searching for folks asking about setting the affinity of a process in AutoIT, the last time I saw anyone mention it was way back in 2005. Even then, it was a cloudy mystery for anyone who wasn't sure about DLL calls. Welp, thanks to the pieces of that thread, the MSDN knowledgebase, and a bit of peeking into some of the Include AU3's on how to properly do the calls, I have written a very simple SetProcessAffinity function to let you change the affinity of a given process tree. You'll need to know the PID of your process (easy if you're using the built-in AutoIT Run function) to make it work. Here it is: expandcollapse popup;; Function ProcessSetAffinity ;; ;; Inputs: ;; iProcessID - the PID of the process to change affinity ;; iProcessor - the integer value of the binary affinity bitmask (see below) ;; ;; Results: ;; Returns -1 and sets @error = 1 if the process doesn't exist ;; Returns -1 and sets @error = 2 if this script isn't able to get sufficient access to the process handle ;; Returns 1 if the affinity was set to your request ;; Returns 0 if the affinity could not be set ;; ;; How Affinity Bitmasks Work: ;; ;; Bitmasks are a binary representation of what processor(s) a thread or process is allowed to run on ;; One binary digit per CPU, a zero means it -cannot- run on that CPU, a one means it -can- run on that CPU ;; So, if your machine has two processors: ;; ;; Binary | Integer | Description ;; 01 = 1 = Can run on the first CPU, but not the second ;; 10 = 2 = Can run on the second CPU, but not the first ;; 11 = 3 = Can run on the first and second CPU's ;; ;; If your machine had four processors: ;; ;; 0001 = 1 = Can run on the first CPU, but not the second, third or fourth ;; 0010 = 2 = Can run on the second CPU, but not the first, third or fourth ;; 0011 = 3 = Can run on the first and second CPU's, but not the third or fourth ;; 0100 = 4 = Can run on the third CPU, but not the first, second or fourth ;; 0101 = 5 = Can run on the first and third CPU's, but not the second or fourth ;; ... (continued ad-nauseum) Func ProcessSetAffinity($iProcessID,$iProcessor = 1) Local $i_PID = ProcessExists($iProcessID) If Not $i_PID Then SetError(1) Return -1 EndIf Local $hDLL = DllOpen('kernel32.dll') Local $aProcessHandle = DllCall($hDLL, 'int', 'OpenProcess', 'int', 0x0200, 'int', False, 'int', $i_PID) if $aProcessHandle[0] = 0 Then SetError(2) Return -1 EndIf Local $aAffinity = DllCall($hDLL, 'int', 'SetProcessAffinityMask', 'int', $aProcessHandle[0], 'int', $iProcessor) DllCall($hDLL, 'int', 'CloseHandle', 'int', $aProcessHandle[0]) DllClose($hDLL) Return $aAffinity[0] EndFunc ;==>ProcessSetAffinity Hope someone gets use out of it
DW1 Posted December 11, 2007 Posted December 11, 2007 Very nice, thank you, I will use it. AutoIt3 Online Help
SandelPerieanu Posted December 12, 2007 Posted December 12, 2007 expandcollapse popup;CPU0 and CPU1 selected - BinToDec(11)=3 result $affinity=3 ;CPU0 selected - BinToDec(01) = 1 result $affinity=1 ;CPU1 selected - BinToDec(10) = 2 result $affinity=2 ; ;$action - 'Show' return affinity state ; - 'Set' return affinity after modification ; ;Return = Process Mask / System Mask MsgBox(0, '', ProcessAffinity('Show')) MsgBox(0, '', ProcessAffinity('Set', 2)) MsgBox(0, '', ProcessAffinity('Set', 3)) Func ProcessAffinity($aaction, $affinity = '', $pid_process = @AutoItPID) Local $hprocess = DllCall("Kernel32.dll", "int", "OpenProcess", "int", 0x1F0FFF, "int", False, "int", $pid_process) Local $amask[3], $rbuffer, $psystem, $aresult, $pprocess, $iresult $rbuffer = DllStructCreate("int;int") $pprocess = DllStructGetPtr($rbuffer, 1) $psystem = DllStructGetPtr($rbuffer, 2) $aresult = DllCall("Kernel32.dll", "int", "GetProcessAffinityMask", "hwnd", $hprocess[0], "ptr", $pprocess, "ptr", $psystem) $amask[0] = $aresult[0] <> 0 $amask[1] = DllStructGetData($rbuffer, 1) $amask[2] = DllStructGetData($rbuffer, 2) If $affinity - 0 = 0 Or $affinity > $amask[2] Then $affinity = $amask[2] Select Case $aaction = 'Show' DllCall("Kernel32.dll", "int", "CloseHandle", "int", $hprocess[0]) Return $amask[1] & '/' & $amask[2] Case $aaction = 'Set' $iresult = DllCall("Kernel32.dll", "int", "SetProcessAffinityMask", "hwnd", $hprocess[0], "int", $affinity) $aresult = DllCall("Kernel32.dll", "int", "GetProcessAffinityMask", "hwnd", $hprocess[0], "ptr", $pprocess, "ptr", $psystem) $amask[1] = DllStructGetData($rbuffer, 1) $amask[2] = DllStructGetData($rbuffer, 2) DllCall("Kernel32.dll", "int", "CloseHandle", "int", $hprocess[0]) Return $amask[1] & '/' & $amask[2] EndSelect EndFunc ;==>ProcessAffinity
Recommended Posts
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 accountSign in
Already have an account? Sign in here.
Sign In Now