簡體   English   中英

如何在批處理腳本中使用 WMIC 獲取內存利用率百分比?

[英]How to get the Percentage of memory utilization using WMIC in batch script?

我沒有得到僅使用 W MIC 的批處理腳本中內存利用率百分比的結果。 我只得到總內存和可用內存(以字節為單位)。

那么如何獲得以兆字節為單位的數據以及如何計算內存利用率的百分比?

代碼:-

@echo off
setlocal enabledelayedexpansion

set Times=0
for /f "skip=1" %%p in ('wmic cpu get loadpercentage') do (
    set Cpusage!Times!=%%p
    set /A Times+=1
)

echo CPU Percentage = %Cpusage0%%%

set Times=0
for /f "skip=1" %%p in ('wmic ComputerSystem get TotalPhysicalMemory') do (
    set totalMem!Times!=%%p
    set /A Times+=1
)

set Times=0
for /f "skip=1" %%p in ('wmic OS get FreePhysicalMemory') do (
    set availableMem!Times!=%%p
    set /A Times+=1
)

set Times=0
for /f "skip=1" %%p in ('wmic OS get FreePhysicalMemory ^|findstr physical') do (
    set /a UsedMem= totalMem - availableMem
    set usedMem!Times!=%%p
    set /A Times+=1
)
set /a usedpercent=(usedMem*100)/totalMem

echo Free MEMORY = %availableMem0% Bytes
echo Total MEMORY = %totalMem0% Bytes
echo Used MEMORY = %UsedMem0% Bytes
echo Memory Utilization = %usedpercent0%%%

pause

如果確實沒有必要多次使用setlocal ,則setlocal enabledelayedexpansion通常只應在批處理文件中使用一次。 此命令不只是啟用延遲擴展模式。 它還始終復制整個當前環境表(最多 64 MB)、命令擴展和延遲擴展的當前狀態以及堆棧(內存)上的當前目錄路徑。 此類環境推入堆棧的數量不是無限的。 至少使用endlocal between 以避免由於堆棧溢出而提前退出批處理。 有關更多詳細信息,請參閱以下答案:

甚至 64 位 Windows 命令處理器 ( cmd.exe ) 也使用 32 位有符號整數。 因此,值范圍限制為 -2.147.483.648 到 +2.147.483.647。 換句話說,如果沒有整數溢出產生錯誤結果,就無法完成 2 GB 和更多的算術運算。

這是一個帶注釋的批處理文件,它不適用於所有可能的已安裝 RAM 配置,但適用於 2016 年的典型配置:2 GB、4 GB、8 GB、16 GB 和 32 GB。

@echo off

rem Note: KB = KiB, MB = MiB and GB = GiB in this batch file, see
rem       https://en.wikipedia.org/wiki/Byte for details on GiB.

rem Create a copy of current environment variables. Enabling additionally
rem delayed environment variable expansion is not required for this task.
setlocal EnableExtensions DisableDelayedExpansion

rem The command WMIC with the parameters CPU GET LoadPercentage outputs
rem one line per processor. The output of WMIC is in UTF-16 LE with BOM.
rem The output is redirected to a temporary file which is printed by
rem command TYPE to STDOUT which makes a better job on UNICODE to ASCII
rem conversion as command FOR. Note: 1 processor can have 1 or more cores.

set "CpuUsage=0"
set "Processors=0"
%SystemRoot%\System32\wbem\wmic.exe CPU GET LoadPercentage >"%TEMP%\cpu_usage.tmp"
for /F "skip=1" %%P in ('type "%TEMP%\cpu_usage.tmp"') do (
    set /A CpuUsage+=%%P
    set /A Processors+=1
)
del "%TEMP%\cpu_usage.tmp"

rem Calculate the CPU usage as percentage value of all processors.
set /A CpuUsage/=Processors
goto GetTotalMemory

rem Output of WMIC is in UTF-16 LE with BOM. The interpretation of this
rem output in ASCII/OEM can result in processing three lines instead of
rem just two with third line being just a carriage return. Therefore exit
rem each loop after assigning the value of second line to the variable.

:GetTotalMemory
for /F "skip=1" %%M in ('%SystemRoot%\System32\wbem\wmic.exe ComputerSystem GET TotalPhysicalMemory') do set "TotalMemory=%%M" & goto GetAvailableMemory
:GetAvailableMemory
for /F "skip=1" %%M in ('%SystemRoot%\System32\wbem\wmic.exe OS GET FreePhysicalMemory') do set "AvailableMemory=%%M" & goto ProcessValues

rem Total physical memory is in bytes which can be greater 2^31 (= 2 GB)
rem Windows command processor performs arithmetic operations always with
rem 32-bit signed integer. Therefore 2 GB or more installed physical
rem memory exceeds the bit width of a 32-bit signed integer and arithmetic
rem calculations are wrong on 2 GB or more installed memory. To avoid
rem the integer overflow, the last 6 characters are removed from bytes
rem value and the remaining characters are divided by 1073 to get the
rem number of GB. This workaround works only for physical RAM being
rem an exact multiple of 1 GB, i.e. for 1 GB, 2 GB, 4 GB, 8 GB, ...

rem  1 GB =  1.073.741.824 bytes = 2^30
rem  2 GB =  2.147.483.648 bytes = 2^31
rem  4 GB =  4.294.967.296 bytes = 2^32
rem  8 GB =  8.589.934.592 bytes = 2^33
rem 16 GB = 17.179.869.184 bytes = 2^34
rem 32 GB = 34.359.738.368 bytes = 2^35

rem But there is one more problem at least on Windows XP x86. About 50 MB
rem of RAM is subtracted as used by Windows itself. This can be seen in
rem system settings when 1.95 GB is displayed although 2 GB is installed.
rem Therefore add 50 MB before dividing by 1073.

:ProcessValues
set "TotalMemory=%TotalMemory:~0,-6%"
set /A TotalMemory+=50
set /A TotalMemory/=1073

rem The total memory in GB must be multiplied by 1024 to get the
rem total physical memory in MB which is always small enough to
rem be calculated with a 32-bit signed integer.

set /A TotalMemory*=1024

rem The available memory is in KB and therefore there is
rem no problem with value range of 32-bit signed integer.

set /A AvailableMemory/=1024

rem So the used memory in MB can be determined easily.

set /A UsedMemory=TotalMemory - AvailableMemory

rem It is necessary to calculate the percentage value in MB instead of
rem KB to avoid a 32-bit signed integer overflow on 32 GB RAM and nearly
rem entire RAM is available because used is just a small amount of RAM.

set /A UsedPercent=(UsedMemory * 100) / TotalMemory

if "%Processors%" == "1" (
    set "ProcessorInfo="
) else (
    set "ProcessorInfo= of %Processors% processors"
)
echo CPU percentage: %CpuUsage% %%%ProcessorInfo%
echo Free memory:    %AvailableMemory% MB
echo Total memory:   %TotalMemory% MB
echo Used memory:    %UsedMemory% MB
echo Memory usage:   %UsedPercent% %%

rem Discard the current environment variable table and restore previous
rem environment variables. The states of command processor extension
rem (default: ON) and delayed expansion (default: OFF) as well as the
rem original current directory are restored by this command although
rem not modified at all by the commands above.
endlocal

要了解使用的命令及其工作原理,請打開命令提示符窗口,在那里執行以下命令,並仔細閱讀為每個命令顯示的所有幫助頁面。

  • del /?
  • echo /?
  • endlocal /?
  • for /?
  • goto /?
  • rem /?
  • setlocal /?
  • set /?
  • type /?
  • wmic /?
  • wmic CPU get /?
  • wmic OS get /?
  • wmic ComputerSystem get /?

Win32_ComputerSystem類的TotalPhysicalMemory屬性(以字節為單位, uint64數據類型)超出set /A批處理文件整數算術限制(請參閱set命令):它僅限於 32 位精度(對應於uint32數據類型)即 cca ±2吉比特 ( GiB )

讓我們捕獲Systeminfo命令的輸出,以mebibytes ( MiB ) 為單位

==> systeminfo | find /I "Physical Memory"

Total Physical Memory:     8 137 MB
Available Physical Memory: 4 210 MB

==>

因此set /A應該就足夠了:32 位的限制已經不堪重負。

rem評論中的解釋:

@ECHO OFF >NUL
SETLOCAL EnableExtensions
echo(---
set "_memo_total="
    rem unfortunately, next command is (supposedly) locale dependent
for /F "tokens=1,* delims=:" %%G in ('
        systeminfo^|find /I "Physical Memory"
                                    ') do (
  set "_memo_inuse="
      rem remove spaces including no-break spaces
  for %%g in (%%H) do if /I NOT "%%g"=="MB" set "_memo_inuse=!_memo_inuse!%%g"
  if defined _memo_total ( set "_memo_avail=!_memo_inuse!" 
                  ) else ( set "_memo_total=!_memo_inuse!" )
  echo !_memo_inuse! [MB] %%G 
)
set /A "_memo_inuse=_memo_total - _memo_avail"
    rem in integer arithmetics: calculate percentage multipled by 100 
set /A "_perc_inuse=10000 * _memo_inuse / _memo_total"
set /A "_perc_avail=10000 * _memo_avail / _memo_total"
    rem debugging: mostly 9999 as `set /A` trucates quotients instead of rounding  
set /A "_perc__suma=_perc_inuse + _perc_avail
echo(---
call :formatpercent _perc_avail
call :formatpercent _perc_inuse
call :formatpercent _perc__suma
    rem display results
set _
ENDLOCAL
goto :eof

:formatpercent
    rem         simulates division by 100

    rem input : variable NAME (i.e. passed by reference)
    rem         it's value could vary from   0 to 10000   format mask ####0  
    rem output: variable VALUE 
    rem             respectively vary from .00 to 100.00  format mask ###.00
if NOT defined %1 goto :eof
SETLOCAL EnableDelayedExpansion
  set "aux5=     !%1!"
  set "aux5=%aux5:~-5%"
      rem repair unacceptable format mask ###.#0 to ###.00
  set "auxx=%aux5:~3,1%
  if "%auxx%"==" " set "aux5=%aux5:~0,3%0%aux5:~4%"
      REM       rem change format mask from ###.00 to common ##0.00
      REM   set "auxx=%aux5:~2,1%
      REM   if "%auxx%"==" " set "aux5=%aux5:~0,2%0%aux5:~3%" 
  set "aux6=%aux5:~0,3%.%aux5:~3%"
ENDLOCAL&set "%1=%aux6%"
goto :eof

輸出

==> D:\bat\SO\37338476a.bat
---
8137 [MB] Total Physical Memory
4166 [MB] Available Physical Memory
---
_memo_avail=4166
_memo_inuse=3971
_memo_total=8137
_perc_avail= 51.19
_perc_inuse= 48.80
_perc__suma= 99.99

==>

准確度、容差(使用8 GiB安裝內存測量):==>

  • Capacity=8589934592來自Win32_PhysicalMemory類 == 8 GiB
  • TotalPhysicalMemory=8531865600來自Win32_ComputerSystem類 == 8136.62 MiB
  • Total Physical Memory: 8 137 MB來自systeminfo命令 == 8137 MiB

響應時間systeminfowmic慢得多):==>

您可以更改輸出以滿足您的需要:

@if (@X)==(@Y) @end /* JScript comment
    @echo off
    cscript //E:JScript //nologo "%~f0"
    exit /b %errorlevel%

@if (@X)==(@Y) @end JScript comment */

var aBytes=GetObject('winmgmts:').ExecQuery('Select * from Win32_PerfFormattedData_PerfOS_Memory').ItemIndex(0).AvailableBytes;
var tBytes=GetObject('winmgmts:').ExecQuery('Select * from Win32_ComputerSystem').ItemIndex(0).TotalPhysicalMemory;
WScript.Echo("available:"+aBytes+"\ntotal:"+tBytes);
var totalMemoryUsed=(tBytes-aBytes)*100/tBytes;
WScript.Echo("used in % -"+totalMemoryUsed);

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM