2016-05-20 2 views
2

Я не получаю результат для% использования памяти в пакетном скрипте, используя только 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 
+2

Я использовал WMIC команду ComputerSystem прибудет TotalPhysicalMemory, OS прибудет FreePhysicalMemory –

+0

Боюсь, что эта задача неразрешима в 'ЦМДА '. Следующая команда 'for/f 'skip = 1"% G in (' wmic ComputerSystem get TotalPhysicalMemory ') do @for% g in (% G) установить/a% g' возвращает 'Недопустимый номер. Числа ограничены 32-битной точностью. Переключитесь на PowerShell. – JosefZ

+0

Но есть ли способ уменьшить число до 4 цифр, тогда мы можем легко вычислить правильно? пожалуйста, предложите –

ответ

2

setlocal enabledelayedexpansion следует использовать только один раз в пакетном файле, если нет реальной необходимости использовать setlocal несколько раз. Эта команда не просто включает режим с задержкой расширения. Он всегда копирует также всю текущую таблицу окружения (которая может быть до 64 МБ), текущие состояния расширения команд и задержки расширения, а также текущий путь к папке в стеке (память). Количество такой среды, которая нажимает на стек, не является неограниченным.По крайней мере, используйте endlocal, чтобы избежать раннего выхода пакетной обработки из-за переполнения стека. Более подробную информацию см ответы на:

Даже 64-разрядные команды Windows, интерпретатор (cmd.exe) использует 32-битные целые числа. Поэтому диапазон значений ограничен -2,144,483,648 до +2,144,483,647. Другими словами, арифметические операции с более чем 2 ГБ не могут быть выполнены без целочисленных переполнений, что приводит к неправильным результатам.

Вот комментированный пакетный файл, который не работает для всех возможных установленных конфигураций ОЗУ, но работает для тех, которые типичны в 2016 году: 2 ГБ, 4 ГБ, 8 ГБ, 16 ГБ и 32 ГБ.

@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, 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 /?
+0

Для запуска пакетного файла в качестве запланированной задачи для задачи нужно указать учетную запись пользователя. У этой учетной записи должны быть требуемые разрешения. Например, вывод 'wmic.exe CPU get loadpercentage' перенаправляется во временный файл, который создается в папке, заданной переменной окружения __TEMP__. Определена ли эта переменная в среде, определенной для учетной записи пользователя? Имеет ли используемая учетная запись разрешение на создание файла в этом каталоге? И родительский пакетный файл НЕ модифицирует или удаляет переменную __TEMP__? – Mofi

+0

Код работает нормально, вы правы, это была проблема с разрешением. Огромное спасибо!!! –

0

вы можете изменить вывод в соответствии с вашими потребностями:

@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); 
1

TotalPhysicalMemory свойство Win32_ComputerSystem class (в байтах, uint64 тип данных) overreachs set /A Ограниченное число арифметических ограничений пакетного файла (см. set command): оно ограничено 32-битной точностью (соответствует uint32), т. е. cca ± 2 gibibytes (GiB). Выход

Давайте захвата от Systeminfo command, который находится в 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

Время отклика (systeminfo значительно медленнее, чем wmic): = =>бедные

+0

Использование Systeminfo очень легко получить вывод в MB, но оно проверит все исправления и информацию о NIC системы, я надеюсь, что systeminfo не является хорошей идеей, когда мы реализуем этот скрипт на сервере, это займет больше cpu, поэтому только я предпочитаю WMIC –

+0

Итак, пожалуйста, помогите мне в сценарии WMIC, чтобы получить тот же результат –

+0

@ T.Anand см. [мой комментарий к вашему вопросу] (http://stackoverflow.com/questions/37338476/how-to -get-the-of-memory-usage-using-wmic-in-batch-script/37357698? noredirect = 1 # comment62199573_37338476) Вероятно, вам нужно настроить [ответ npocmaka] (http://stackoverflow.com/a/37348677/3439404) в соответствии с вашими обстоятельствами и требованиями. Извините, я не могу писать сценарии для всех на StackExchange.com. Я могу решить сложную задачу при решении интересных задач ... – JosefZ

Смежные вопросы