Jump to content
Sign in to follow this  
Decipher

Get/Limit Process CPU Usage - Background Script

Recommended Posts

Decipher

I took a script written by Beege, optimized the code, and removed the global variables. Its one function, reliable, and very easy to use or modify to your needs. I decided to post it because I found it very hard to find a reliable way to get the cpu percentage of a given process. I know that there are a few different methods but I deem WMI unreliable and everything I tried before optimizing this function was to slow i.e. freezing when other CPU intensive processes were active.

When monitoring a potentially CPU intensive process, I found it necessary to increase the script's priority otherwise the script/system would freeze which is exactly what I was attempting to prevent!

See Beege's updated post: :thumbsup:

#NoTrayIcon
#include <WinAPI.au3>

HotKeySet('{ESC}', '_Exit')
Func _Exit()
    Exit
EndFunc   ;==>_Exit

_LimitProcessCPU("MediaServer.exe", 10, 1, 5)

Func _LimitProcessCPU($vProcess, $nLimit, $nInterval = 1, $nScriptPriority = 2)
    Local $nProcessCpu = -1, $nOverLimit = 0
    While ProcessExists($vProcess)
        $nProcessCpu = _ProcessCPU($vProcess, $nScriptPriority)
        If $nProcessCpu > 50 Then
            $nOverLimit += 1
        Else
            $nOverLimit = 0
        EndIf
        If $nOverLimit > $nLimit Then
            $nOverLimit = 0
            ProcessClose($vProcess) ; < - Replace this with what you need.
        EndIf
        Sleep($nInterval*1000)
    WEnd
EndFunc

Func _ProcessCPU($nPID = @AutoItPID, $nScriptPriority = 2) ; Realtime priority = 5
        ; Original Author: Beege -> http://www.autoitscript.com/forum/user/8949-beege/
    $nPID = ProcessExists($nPID)
    If Not $nPID Then
        Return SetError(1, 0, "")
    EndIf
    Local Const $tagFILETIME = "struct;dword Lo;dword Hi;endstruct", $nStructs = 7
    Local Static $aStruct[$nStructs], $aPointer[$nStructs], $aStat[4], $hProcess  = _WinAPI_OpenProcess(0x1F0FFF, 0, $nPID, True), $bFirstRun = True
    Local Enum $nIDLETIME, $nKERNELTIME, $nUSERTIME, $nPCreationTime, $nPExitTime, $nPKernelTime, $nPUserTime, _
            $nProcStartKern = 0, $nProcStartUser, $nStartKernel, $nStartUser
    If $bFirstRun Then
        For $i = 0 To $nStructs - 1 Step 1
            $aStruct[$i] = DllStructCreate($tagFILETIME)
            $aPointer[$i] = DllStructGetPtr($aStruct[$i])
        Next
    EndIf
    DllCall('Kernel32.dll', "int", "GetSystemTimes", "ptr", $aPointer[$nIDLETIME], "ptr", $aPointer[$nKERNELTIME], "ptr", $aPointer[$nUSERTIME])
    DllCall('Kernel32.dll', "int", "GetProcessTimes", "hwnd", $hProcess, "ptr", $aPointer[$nPCreationTime], "ptr", $aPointer[$nPExitTime], "ptr", _
            $aPointer[$nPKernelTime], "ptr", $aPointer[$nPUserTime])
    Local $aTemp[4] = [DllStructGetData($aStruct[$nPKernelTime], 1), DllStructGetData($aStruct[$nPUserTime], 1), DllStructGetData($aStruct[$nKERNELTIME], 1), _
            DllStructGetData($aStruct[$nUSERTIME], 1)], $tProcess, $tSystem
    If Not $bFirstRun Then
        $tProcess = ($aTemp[$nProcStartKern] - $aStat[$nProcStartKern]) + ($aTemp[$nProcStartUser] - $aStat[$nProcStartUser])
        $tSystem = ($aTemp[$nStartKernel] - $aStat[$nStartKernel]) + ($aTemp[$nStartUser] - $aStat[$nStartUser])
    Else
        ProcessSetPriority(@AutoItPID, $nScriptPriority)
        $bFirstRun = False
    EndIf
    $aStat = $aTemp
    Return Int(Round(($tProcess / $tSystem) * 100))
EndFunc   ;==>_ProcessCPU

Edit - To give credit for source.

Anonymous

Edited by Decipher

Spoiler

censored.jpg

 

Share this post


Link to post
Share on other sites
Ascend4nt

Interesting, I just developed a Process CPU usage tracker not long after my work on the CPU Usage tracker code.  I liked the idea of keeping it more object-oriented, and so far my system works out pretty well.  In the future I might expand it to more than one process per usage tracker, since it'd be a shame to call GetSystemTimes more times than is necessary.

Ah, and the author you should be crediting is probably Beege - see his >Process CPU Usage script.

Share this post


Link to post
Share on other sites
Decipher

Ascend4nt,

I've looked at a lot of your code recently, it looks great! Thanks for the info. ;)

If you like at this line:

DllCall('Kernel32.dll', "int", "GetSystemTimes", "ptr", $aPointer[$nIDLETIME], "ptr", $aPointer[$nKERNELTIME], "ptr", $aPointer[$nUSERTIME])

You will see that the data structures that it populates are resuable for multiple calls to <GetProcessTimes> however I wouldn't know right off wether or not you could get around that function call or not as it requires you pass a process handle.

Anonymous

Edited by Decipher

Spoiler

censored.jpg

 

Share this post


Link to post
Share on other sites
arandomguy01

How's it going?  I'm using the _ProcessCPU function here in a script.  However, occasionally I need to change the monitored Process.  I'm  not quite sure how to do this as it seems the Static variables don't allow it.  Any advice on how to do this?  Thank you for your time.

Share this post


Link to post
Share on other sites
Decipher

arandomguy01,

Here is an example that complements JohnOne's answer.

Global $nPID = "MyProcess.exe"

While 1
    ;_ProcessCPU(3) ; 3 = AboveNormal priority
    ConsoleWrite(_ProcessCPU(3) & "%" & @CRLF)
    If "condition" = "condition" Then
        $nPID = "MyOtherProcess.exe"
    EndIf
    Sleep(1000)
WEnd

Func _ProcessCPU($nScriptPriority = 2) ; Realtime priority = 5
        ; Original Author: Beege -> http://www.autoitscript.com/forum/user/8949-beege/
    $nPID = ProcessExists($nPID)
    If Not $nPID Then
        Return SetError(1, 0, "")
    EndIf
    Static $nLastProcess = $nPID
    If $nPID <> $nLastProcess Then
        $nLastProcess = $nPID
        $hProcess  = _WinAPI_OpenProcess(0x1F0FFF, 0, $nPID, True)
    EndIf
    Local Const $tagFILETIME = "struct;dword Lo;dword Hi;endstruct", $nStructs = 7
    Local Static $aStruct[$nStructs], $aPointer[$nStructs], $aStat[4], $hProcess  = _WinAPI_OpenProcess(0x1F0FFF, 0, $nPID, True), $bFirstRun = True
    Local Enum $nIDLETIME, $nKERNELTIME, $nUSERTIME, $nPCreationTime, $nPExitTime, $nPKernelTime, $nPUserTime, _
            $nProcStartKern = 0, $nProcStartUser, $nStartKernel, $nStartUser
    If $bFirstRun Then
        For $i = 0 To $nStructs - 1 Step 1
            $aStruct[$i] = DllStructCreate($tagFILETIME)
            $aPointer[$i] = DllStructGetPtr($aStruct[$i])
        Next
    EndIf
    DllCall('Kernel32.dll', "int", "GetSystemTimes", "ptr", $aPointer[$nIDLETIME], "ptr", $aPointer[$nKERNELTIME], "ptr", $aPointer[$nUSERTIME])
    DllCall('Kernel32.dll', "int", "GetProcessTimes", "hwnd", $hProcess, "ptr", $aPointer[$nPCreationTime], "ptr", $aPointer[$nPExitTime], "ptr", _
            $aPointer[$nPKernelTime], "ptr", $aPointer[$nPUserTime])
    Local $aTemp[4] = [DllStructGetData($aStruct[$nPKernelTime], 1), DllStructGetData($aStruct[$nPUserTime], 1), DllStructGetData($aStruct[$nKERNELTIME], 1), _
            DllStructGetData($aStruct[$nUSERTIME], 1)], $tProcess, $tSystem
    If Not $bFirstRun Then
        $tProcess = ($aTemp[$nProcStartKern] - $aStat[$nProcStartKern]) + ($aTemp[$nProcStartUser] - $aStat[$nProcStartUser])
        $tSystem = ($aTemp[$nStartKernel] - $aStat[$nStartKernel]) + ($aTemp[$nStartUser] - $aStat[$nStartUser])
    Else
        ProcessSetPriority(@AutoItPID, $nScriptPriority)
        $bFirstRun = False
    EndIf
    $aStat = $aTemp
    Return Int(Round(($tProcess / $tSystem) * 100))
EndFunc   ;==>_ProcessCPU

Edit - Do notice that I slightly modified the function for use with the global variable.

Anonymous

Edited by Decipher

Spoiler

censored.jpg

 

Share this post


Link to post
Share on other sites
Beege

Interesting, I just developed a Process CPU usage tracker not long after my work on the CPU Usage tracker code.  I liked the idea of keeping it more object-oriented, and so far my system works out pretty well.  In the future I might expand it to more than one process per usage tracker, since it'd be a shame to call GetSystemTimes more times than is necessary.

 

Ah, and the author you should be crediting is probably Beege - see his >Process CPU Usage script.

 

Thanks for the credit point out Ascend4nt. Ive thought about doing the same type of expansion myself with the code below and passing an array of process handles. My only worry was how far off would the system times be by the time I got to the last call of getprocesstimes. But might be over thinking it  :wacko:

 

 Decipher,

Heres another example you could adapt from thats a little cleaner then I wrote back then with more of the updated syntax that autoit currently has. When I originally wrote it the main thought in my head was everything could be all in one function cause Im only monitoring the process itself. Hense the static var for the process handle. If the handle might change, I would recommend functions like below that except the handle as a parameter. I realize it was just a quick fix, but a global var that changes a local static var is not a good choice. Also note the use of the _ProcessExists function Im using. Its much more efficient than autoits built in one due to how autoit enumerates all processes, then goes throught the list looking for the pid. This returns both total cpu and process cpu. 

#AutoIt3Wrapper_UseX64=n

#include <winapi.au3>
#include <Timers.au3>

;Press ESC to Exit
HotKeySet('{ESC}', '_Exit')

;Press Alt-L to generate a test load
HotKeySet('!l', '_TestLoad')

;Define requested access rights depending on which os is being used
Global $iAccess = 0x0400 ; PROCESS_QUERY_INFORMATION (xp)
If (@OSBuild > 3790) Then $iAccess = 0x1000 ; PROCESS_QUERY_LIMITED_INFORMATION (Vista and up)

;Get Handle to autoit process
Global $g_hAutoItProcess = _WinAPI_OpenProcess($iAccess, 0, @AutoItPID)
If @error Then Exit (ConsoleWrite('Error getting handle' & @LF))

;Call _GetProcessCPU() 1/sec
AdlibRegister('_ProcessCPUExample', 1000)

;Sleep till exit
While Sleep(600000)
WEnd


Func _ProcessCPUExample()

    Static Local $aEnd, $aStart = _GetProcessUsage($g_hAutoItProcess)

    $aEnd = _GetProcessUsage($g_hAutoItProcess)

    ;Get both total and process cpu usage
    Local $aCPU = _CalcUsage($aStart, $aEnd)

    ;Make sure cpu values are valid
    If $aCPU[0] >= 0 And $aCPU[0] <= 100 Then
        ConsoleWrite('Total CPU Usage = ' & $aCPU[0] & '%' & @TAB & @TAB & 'AutoIt CPU Usage = ' & $aCPU[1] & '%' & @LF)
    EndIf

    ;copy last cpu times to start.
    $aStart = $aEnd

EndFunc   ;==>_GetProcessCPU

Func _GetProcessUsage($hProc)

    Static Local $tIdle = DllStructCreate("dword;dword"), $tUser = DllStructCreate("dword;dword"), $tKernel = DllStructCreate("dword;dword")
    Static Local $tCreation = DllStructCreate("dword;dword"), $tExit = DllStructCreate("dword;dword")

    ;Make sure process still exists
    If Not _ProcessExists($hProc) Then Return SetError(1, 0, -1)

    ;Array for holding idle, System and process cpu times
    Local $aTimes[3]

    ;Get system CPU times
    DllCall('Kernel32.dll', "int", "GetSystemTimes", "struct*", $tIdle, "struct*", $tUser, "struct*", $tKernel)
    $aTimes[0] = DllStructGetData($tIdle, 1)
    $aTimes[1] = DllStructGetData($tUser, 1) + DllStructGetData($tKernel, 1)

    ;Get Process cpu times
    DllCall('Kernel32.dll', "int", "GetProcessTimes", "handle", $hProc, "struct*", $tCreation, "struct*", $tExit, "struct*", $tKernel, "struct*", $tUser)
    $aTimes[2] = DllStructGetData($tUser, 1) + DllStructGetData($tKernel, 1)

    Return $aTimes

EndFunc   ;==>_GetProcessUsage

Func _CalcUsage($aCpuStart, $aCpuEnd, $nPercent = True)

    ;Calculate time difference for idle, system, process
    Local $iIdle = ($aCpuEnd[0] - $aCpuStart[0]), $iSystem = ($aCpuEnd[1] - $aCpuStart[1]), $iProcess = ($aCpuEnd[2] - $aCpuStart[2])

    ;Calculate Total and Process CPU values
    Local $aCPUTimes[2]
    $aCPUTimes[0] = ($iSystem - $iIdle) / $iSystem ;    Total CPU Usage
    $aCPUTimes[1] = $iProcess / $iSystem ;              Process CPU Usage

    ;Convert to percent
    If $nPercent Then
        $aCPUTimes[0] = Round($aCPUTimes[0] * 100)
        $aCPUTimes[1] = Round($aCPUTimes[1] * 100)
    EndIf

    Return $aCPUTimes

EndFunc   ;==>_CalcUsage

Func _ProcessExists($hProc)

    Local $aRet = DllCall('kernel32.dll', 'bool', 'GetExitCodeProcess', 'handle', $hProc, 'dword*', 0)
    If @error Or $aRet[0] = 0 Then Return SetError(1, 0, 0)

    Return ($aRet[2] = 259)

EndFunc   ;==>_ProcessExists

Func _TestLoad()
    Local $iA
    For $i = 1 To 500000
        $iA = $iA / 3
    Next
EndFunc   ;==>_TestLoad

Func _Exit()
    _WinAPI_CloseHandle($g_hAutoItProcess)
    Exit
EndFunc   ;==>_Exit
Edit: Changes to OpenProcess. Access rights should be set according to OS version used. Also debug privilages not needed in this case. Edited by Beege
  • Like 1

Share this post


Link to post
Share on other sites
Decipher

Beege,

Thanks for the awesome(efficient) code again! I'll definitely be updating my scripts. So the new dll call syntax removes the need to call DllStructGetPtr directly, hu? I had no idea that AutoIt's ProcessExists() function behaved that way. I'll be adding your functions to my reference list. ;)

Anonymous


Spoiler

censored.jpg

 

Share this post


Link to post
Share on other sites
Beege

Your very welcome. And yes, Struct* gives us the ability to pass a pointer to a struct now so no extra calls to DllStructGetPtr in most cases. 

One other tip, Static is very useful for calling function once, even if your not storing anything in the variable:

Static Local $SetPrioityOnce = ProcessSetPriority(@AutoItPID, $nScriptPriority)

Share this post


Link to post
Share on other sites
kevin3
 

 

When using the above I got occasional negative values. Found it was due to the idle time value rolling over (only the PCU percentage was checked not the Process Percentage). Also sometimes it would have no time elapse between measurements (Some OS caching the function call?) which resulted in incorrect 0% CPU time for the measured Process.
 
Here is the error checking:
Func _ProcessCPUExample()
   
    Static Local $aEnd, $aStart = _GetProcessUsage($g_hAutoItProcess)
    sleep(2000) ; make sure some time elapses between measurements. 
    $aEnd = _GetProcessUsage($g_hAutoItProcess)
    
    ;Make sure time value did not roll over
    while $aEnd[0] <= $aStart[0] or $aEnd[1] <= $aStart[1] or $aEnd[2] <= $aStart[2] 
      ConsoleWrite('ReTrying'&@CRLF)
      $aStart = _GetProcessUsage($g_hAutoItProcess)
      sleep(2000)
      $aEnd = _GetProcessUsage($g_hAutoItProcess)
    WEnd
    
    ;Get both total and process cpu usage
    Local $aCPU = _CalcUsage($aStart, $aEnd)
    ConsoleWrite('Total CPU Usage = ' & $aCPU[0] & '%' & @TAB & @TAB & 'AutoIt CPU Usage = ' & $aCPU[1] & '%' & @LF)

    ;copy last cpu times to start.
    $aStart = $aEnd

EndFunc   ;==>_GetProcessCPU 

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
Sign in to follow this  

  • Similar Content

    • marcoauto
      By marcoauto
      Ciao
      I would like to control an ATEM Video Mixer from autoit. I downloaded his SDK which is written in c ++ and I found the sequences to interface, but I was not able to convert the script to self.
      The instructions say to follow this sequence:
      and to connectTo with C++ is:
      string address = "192.168.1.240"; _BMDSwitcherConnectToFailure failureReason = 0; IBMDSwitcher switcher = null; var discovery = new CBMDSwitcherDiscovery(); discovery.ConnectTo(address, out switcher, out failureReason); From Blackmagic SDK:
      IBMDSwitcherDiscovery::ConnectTo method
      The ConnectTo method connects to the specified switcher and returns an IBMDSwitcher object interface for the switcher.
      Syntax HRESULT ConnectTo (string deviceAddress, IBMDSwitcher** switcherDevice, BMDSwitcherConnectToFailure* failReason); Parameters: deviceAddress in Network hostname or IP address of switcher to connect to. switcherDevice out IBMDSwitcher object interface for the connected switcher. failReason out Reason for connection failure as a BMDSwitcherConnectToFailure value. So, I have I tried these solutions but with non success:
      $DllName =@ScriptDir&"\BMDSwitcherAPI.dll" $result = DllCall($DllName, "none", "IBMDSwitcherDiscovery::ConnectTo" & @CRLF) ConsoleWrite("DLLCall Result: " & $result & @CRLF) and I have tried also create an Object (That I think is the best way solution):
      #include <MsgBoxConstants.au3> $oSwitcher=ObjCreate("IBMDSwitcher") If IsObj($oSwitcher) Then MsgBox(64, "", "Object $oSwitcher created successfully") EndIf $oAtem=ObjCreate("IBMDSwitcherDiscovery") If IsObj($oAtem) Then MsgBox(64, "", "Object $oAtem created successfully") EndIf $failureReason =ObjCreate("_BMDSwitcherConnectToFailure") If IsObj($failureReason) Then MsgBox(64, "", "Object $failureReason created successfully") EndIf $oMyError = ObjEvent("AutoIt.Error", "MyErrFunc") ; Install a custom error handler Global $errore,$oSwitcher1 $oAtem.ConnectTo("192.168.1.36",$oSwitcher,$failureReason); ; This is the custom error handler Func MyErrFunc() $HexNumber = Hex($oMyError.number, 8) MsgBox(0, "", "We intercepted a COM Error !" & @CRLF & _ "Number is: " & $HexNumber & @CRLF & _ "Windescription is: " & $oMyError.windescription & @CRLF & _ "Source is: " & $oMyError.source & @CRLF & _ "Description is: " & $oMyError.description & @CRLF & _ "Helpfile is: " & $oMyError.helpfile & @CRLF & _ "Helpcontext is: " & $oMyError.helpcontext & @CRLF & _ "Lastdllerror is: " & $oMyError.lastdllerror & @CRLF & _ "Scriptline is: " & $oMyError.scriptline) EndFunc ;==>MyErrFunc But the result is:
      We intercepted a COM Error !
      Number is: 000000A9
      Windescription is: Variable must be of type 'Object'.
      Source is: 
      Description is: 
      Helpfile is: 
      Helpcontext is: 
      Lastdllerror is: 0
      Scriptline is: 17
      The BMDSwitcherAPI.dll is registered in system. Can someone help me?
      Grazie
      Marco
    • Seminko
      By Seminko
      I'm trying to get data from http://poe.trade/ - disclaimer, although this site is about a game, my script will not in any way interact directly with the game in any way. The script is just to get data from the site.
      To explain how it works - you submit a POST request and a custom URL is returned, then you do a GET request on that URL and you get the final URL you want.
       
      First issue:
      Now, I've tried doing so by using https://apitester.com/ and the first phase works. Here's how it looks like at APITester:
      Request Headers POST /search HTTP/1.1 Host: poe.trade Accept: */* User-Agent: Rigor API Tester Content-Length: 43 Content-Type: application/x-www-form-urlencoded Request Body online=x&name=kaom%27s%20heart&league=incursion When I submit this, the response I get is this:
      <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN"> <title>Redirecting...</title> <h1>Redirecting...</h1> <p>You should be redirected automatically to target URL: <a href="http://poe.trade/search/ioritewoteteme">http://poe.trade/search/ioritewoteteme</a>. If not click the link. So I then do a GET request for 'http://poe.trade/search/ioritewoteteme', which results in this response:
      <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN"> <title>Redirecting...</title> <h1>Redirecting...</h1> <p>You should be redirected automatically to target URL: <a href="http://poe.trade/search/inamotezuakito">http://poe.trade/search/inamotezuakito</a>. If not click the link. Great, this link (http://poe.trade/search/inamotezuakito) is exactly what we want.
      However, when I try to do the same in autoit, the result is quite different:
      Global Const $HTTP_STATUS_OK = 200 $test = HttpPost("http://poe.trade/search", "/online=x&name=kaom%27s%20heart&league=incursion") ClipPut($test) MsgBox(1, "", $test) Func HttpPost($sURL, $sData = "") Local $oHTTP = ObjCreate("WinHttp.WinHttpRequest.5.1") $oHTTP.Open("POST", $sURL, False) If (@error) Then Return SetError(1, 0, 0) $oHTTP.SetRequestHeader("Host", "poe.trade") $oHTTP.SetRequestHeader("User-Agent", "Rigor API Tester") $oHTTP.SetRequestHeader("Accept", "*/*") $oHTTP.SetRequestHeader("Content-Type", "application/x-www-form-urlencoded") $oHTTP.Send($sData) If (@error) Then Return SetError(2, 0, 0) If ($oHTTP.Status <> $HTTP_STATUS_OK) Then Return SetError(3, 0, 0) Return SetError(0, 0, $oHTTP.ResponseText) EndFunc The code above returns: ' 謟 '
      Any ideas as to what I am doing incorrectly?
       
      Second issue:
      Once I get the final link using APITester and do a GET on that i get a bunch of hieroglyphs. A friend of mine advised that the data is GZiped, which is a pain in the butt to be honest. However, apparently curl can uncompres that.
      How would I go about it?
       
      Thanks
    • argumentum
      By argumentum
      The back story:
      I've got a Dell XPS w/ i7-8700K. The fastest, by single core, I could get, by well known PC maker.
      The problem is that the fan can get so loud, like, REALLY LOUD, I can not use the CPU at its max. clock speed.
      I could leave it at 90% all the time and not use this but I want to have the full 4.x Ghz and no parked cores, at all times, if I can.
      But as room temperature and CPU load changes, a set throttle, may still make fan noise.
      The solution:
      To avoid the fan from going "airplane turbine mode", the utility gets the temp. from "Core Temp" ( you can google it )
      It has a"plug-in" called "Core Temp Remote Server". The utility gets the values via TCP.
      When it "feels" it's gonna get hot, drops the CPU throttle to a selected value, lets say 99% ( where is quieter ) and back up to 100% when it "feels" is ok to go back.
      Now temperature can creep up to higher than expected if load is sustained or room temperature changes. So there is an "anti creep up" feature, to temporarily set the throttle even lower, 5% at a time, until the known quiet temperature is achieved.
      If don't know how to find the temperature you should use, check out these videos. They will tell you how.
      https://www.youtube.com/watch?v=p3B5WCJZTuw&ab_channel=SergeantPope-KomadaComputerRepair
      https://www.youtube.com/watch?v=VuP6I0mOb1s&ab_channel=Techquickie
      https://www.google.com/search?q=find+max+cpu+temperature
      The end result:
      Any thermal problem, is a hardware problem. No way around that, other than attending to the CPU cooling and case ventilation. Software can not fix that.
      But without this utility, the PC would slow down the CPU anyway, to keep it from melting.
      This software preemptively slow down the CPU, keeping the CPU related fan speeds from going to maximum RPM. Hence having a slower, but a quieter box.
    • red0fireus
      By red0fireus
      Hello, I'm very stumped with finding the decimal place for the CPU %.
      I found some example code online
      #include <Array.au3> $aProcess_Info = GetCPU("RzSynapse") _ArrayDisplay($aProcess_Info) Func GetCPU($sProcess = "") Local $aAllProcess_Info[1000][3] = [[0]], $aOneProcess_Info[3] $oWinMgmts = ObjGet("winmgmts:\\.\root\cimv2") $aCPU_Usage = $oWinMgmts.ExecQuery("SELECT Name, IDProcess, PercentProcessorTime FROM Win32_PerfFormattedData_PerfProc_Process") For $vCPU_Info In $aCPU_Usage If $sProcess Then If $vCPU_Info.Name = $sProcess Then $aOneProcess_Info[0] = $sProcess $aOneProcess_Info[1] = $vCPU_Info.IDProcess $aOneProcess_Info[2] = $vCPU_Info.PercentProcessorTime & " %" Return $aOneProcess_Info EndIf Else $aAllProcess_Info[0][0] += 1 $aAllProcess_Info[$aAllProcess_Info[0][0]][0] = $vCPU_Info.Name $aAllProcess_Info[$aAllProcess_Info[0][0]][1] = $vCPU_Info.IDProcess $aAllProcess_Info[$aAllProcess_Info[0][0]][2] = $vCPU_Info.PercentProcessorTime & " %.1f" EndIf Next ReDim $aAllProcess_Info[$aAllProcess_Info[0][0] +1][3] Return $aAllProcess_Info EndFunc ;==>GetCPU Currently the code shows the CPU % as 0 % and I want to show 0.0 % I found this online for strings "%.1f" but i'm not sure how to incorporate it.
    • b9k
      By b9k
      Hi, I am stuck on a GUI problem and would like your help to solve it.
      I am trying to automate the SoundWire Server app to match my current system volume level while it is minimized to the notification area (so no clicking or stealing focus),
      I can already get the handle and alter the tracker position by sending a WM_SETPOS message, but somehow the actual volume is not changed: I think I need to do something else to trigger the event handler for the value change and propagate it correctly.
      This is the control summary from Au3 info:
      >>>> Window <<<< Title: SoundWire Server Class: #32770 Position: 441, 218 Size: 566, 429 Style: 0x94CA00C4 ExStyle: 0x00050101 Handle: 0x0000000000510E12 >>>> Control <<<< Class: msctls_trackbar32 Instance: 4 ClassnameNN: msctls_trackbar324 Name: Advanced (Class): [CLASS:msctls_trackbar32; INSTANCE:4] ID: 6002 Text: Position: 51, 222 Size: 47, 126 ControlClick Coords: 1, 101 Style: 0x5001000A ExStyle: 0x00000000 Handle: 0x00000000001234C8 >>>> Mouse <<<< Position: 496, 567 Cursor ID: 2 Color: 0xF0F0F0 >>>> StatusBar <<<< >>>> ToolsBar <<<< >>>> Visible Text <<<< Default multimedia device Tray on Start Static Server Address: 192.168.1.8 Status: Connected to B9K~OP3 Audio Output Audio Input Level Record to File Input Select: 44.1 kHz Minimize to Master Volume Mute >>>> Hidden Text <<<< Slider2 Mute OK Cancel Label Balance Slider1 Volume Front L/R Fr C/LFE Side L/R Back L/R
      I am attaching the program in question so you don't have to install it (i don't know if it is portable enough, tough): 

      SoundWire Server_files.zip

      Thanks in advance and I hope I didn't post in the wrong section
×