如何在批处理脚本中使用WMIC获得内存利用率的百分比?

我没有得到仅使用WMIC批处理脚本的内存利用率的结果。 我只获得了总字节数和空闲内存。

那么如何以MB为单位以及如何计算内存利用率?

代码1: –

@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 

代码2: –

 @echo off setlocal enabledelayedexpansion set Times=0 for /f "skip=1" %%p in ('wmic cpu get loadpercentage ') do ( set Cpusage=%%p goto :done ) :done echo CPU Percentage: %Cpusage%%% setlocal enabledelayedexpansion set Times=0 for /f "skip=1" %%p in ('wmic os get freephysicalmemory') do ( set availableMem=%%p set /a availableMem=%%p/1024 goto :done ) :done echo Free MEMORY: %availableMem% MB setlocal enabledelayedexpansion set Times=0 for /f "skip=1" %%p in ('wmic ComputerSystem get TotalPhysicalMemory') do ( set /a totalMem0/=1024 set totalMem=%%p goto :done ) :done echo Total MEMORY: %totalMem% setlocal enabledelayedexpansion set Times=0 set usedMem=%%p set /a usedMem=totalMem-availableMem set /a usedpercent=(usedMem*100) / totalMem goto :done :done echo Used MEMORY: %usedMem% echo MEMORY usage: %usedpercent%%% pause 

Solutions Collecting From Web of "如何在批处理脚本中使用WMIC获得内存利用率的百分比?"

setlocal enabledelayedexpansion只能在批处理文件中使用一次,如果没有必要多次使用setlocal 。 该命令不仅启用延迟扩展模式。 它总是复制整个当前环境表(最多可达64 MB),命令扩展和延迟扩展的当前状态以及堆栈(内存)上的当前目录路径。 这种环境的数量并不是无限的。 至少使用endlocal来避免由于堆栈溢出而导致批处理过早退出。 欲了解更多详情,请参阅以下答案:

  • 在批处理中回应URL
  • 为什么我的cd%myVar%被忽略?

即使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/Gibibyte 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 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 more than 2 GB installed physical rem memory exceeds the bit width of a 32-bit signed integer and arithmetic rem calculations are wrong on more than 2 GB 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, ie 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数据类型)overreachs set /A批处理文件整数算术限制(见set命令 ):它限于32位精度(对应于uint32数据类型),即cca±2 gibibytes( GiB ) 。

我们来捕获在mebibytes( MiB )中的 Systeminfo命令的输出:

 ==> 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 (ie 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=8589934592Win32_PhysicalMemory类== 8 GiB
  • TotalPhysicalMemory=8531865600Win32_ComputerSystem类== 8136.62 MiB
  • Total Physical Memory: 8 137 MB来自systeminfo命令== 8137 MiB Total Physical Memory: 8 137 MB

响应时间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);