Script to run a program at a certain CPU load

2019-07-29 02:30发布

问题:

I have tried for like 3 hours now, with multiple codes similar to this:

wmic cpu get loadpercentage > Load.txt
findstr "%random:~,1%" Load.txt > Load1.txt
set load=<Load1.txt
if %load%==" 2 7                              " echo yes
pause

But they all run in to a similar problem, the output of wmic cpu get loadpercentage:

LoadPercentage
56

The format just doesn't allow it to be put into a variable, so I can't check it for anything. Perferably, I would like it to be done in Windows CMD and/or Powershell.

Thanks for the help!

EDIT:

Thanks to @lit for the code, here's my final code that works perfectly:

:: To find the "GUID" or the codes for each power plan, run the command in CMD "powercfg -list".
set HighPerformanceMode=8c5e7fda-e8bf-4a96-9a85-a6e23a8c635c
set PowerSaverMode=a1841308-3541-4fab-bc81-f71556f20b4a

:loop
SETLOCAL ENABLEDELAYEDEXPANSION
SET "load="

FOR /F "usebackq skip=1 tokens=*" %%f IN (`wmic cpu get loadpercentage`) DO (
    IF "!load!" EQU "" (
        set "load=%%~f"
    )
)

if "%load%" geq "65" (
    ping localhost -n 2 >nul
    if "%load%" geq "65" (
        %systemroot%\System32\powercfg.exe /setactive %HighPerformanceMode%
        )
    ) else (
        if "%load%" lss "25" (
            ping localhost -n 2 >nul
            if "%load%" lss "25" (
                %systemroot%\System32\powercfg.exe /setactive %PowerSaverMode%
                )
            )
)

endlocal
ping localhost -n 3 > nul
goto loop

Make sure you change the HighPerformanceMode and PowerSaverMode to have your computer specific power plans. You can find the codes by doing powercfg -list in cmd.

I then made a separate short script that just has "C:\Load Batch\Load Batch.bat" in it, but you have to change it to wherever the main script is. Then I used a program called "BAT to EXE converter" and put it in Ghost Mode, and put the newly made .exe program into my startup folder.

EDIT 2:

I don't believe that my question is a duplicate, the linked question is about getting CPU and RAM usage for what appears to be just to view it, while my question is about getting the load percentage as a pure text form to be used in a script. I am aware of it only testing for one CPU core, but as one goes up it is very likely that the others have similar loads. I had searched this site for code that would separate the "LoadPercentage" text when wmic cpu get loadpercentage is ran, because I couldn't set it into a variable that way.

回答1:

It is likely that the problem is that wmic output is in Unicode. How about going with PowerShell?

Get-CimInstance -ClassName CIM_Processor | select LoadPercentage

I am not sure from the question about what needs to run.

The typical fallback of cmd shell programmers is usually something like:

@ECHO OFF
SETLOCAL ENABLEDELAYEDEXPANSION
SET "X="

FOR /F "usebackq skip=1 tokens=*" %%f IN (`wmic cpu get loadpercentage`) DO (
    IF "!X!" EQU "" (
        set "X=%%~f"
    )
)

ECHO X is %X%

EDIT:

Actually, there will be a LoadPercentage emitted for each core. You probably want the arithmetic mean (average) of them.

Get-CimInstance -ClassName CIM_Processor |
    Measure-Object -Property LoadPercentage -Average |
    Select Average

Doing this in a cmd script would involve summing the LoadPercentage values and dividing by the count of them.

SET /A TOTAL=0
SET /A CORE_COUNT=0

FOR /F "usebackq skip=1" %%t IN (`type NUL ^| wmic /node:"%SERVER_NAME%" cpu get loadpercentage ^| findstr .`) DO (
    IF "%%t" NEQ "" (
        SET /A TOTAL=!TOTAL! + %%t
    )
    SET /A CORE_COUNT=!CORE_COUNT! + 1
)

SET /A AVG_UTILIZATION=%TOTAL% / %CORE_COUNT%

ECHO Number of cores: %CORE_COUNT%
ECHO Total CPU utilisation: %TOTAL%
ECHO Average CPU utilisation: %AVG_UTILIZATION%%%


回答2:

Although writing to a (temporary) file and reading it back with set /p is a possible and valid way, the usual way of getting the output of a command into a variable in cmd is a for /f loop:

for /f "" %%a in ('wmic cpu get loadpercentage /value ^|find "="') do set /a "%%a"
echo %loadpercentage%

As in lits answer, a find (or findstr) command is used to convert the Unicode output of wmic to a "cmd compatible" format.
I use the /value parameter to get an outputformat that's easier to parse and set /a to get a numeric value (no need to mess with spaces).

The benefit of using /value is, you can easily get more than one parameter from the same wmic command:

for /f "delims=" %%a in ('"wmic cpu get Caption,CurrentClockSpeed,ExtClock,L2CacheSize /value |findstr = "') do set "_%%a"
set _

Enclosing the complete command in quotes removes the need of escaping special chars. Of course this works only, if you don't need quotes in the commandstring itself.

(without quoting:

for /f "delims=" %%a in ('wmic cpu get Caption^,CurrentClockSpeed^,ExtClock^,L2CacheSize /value ^|findstr = ') do set "_%%a"

)