Войти

Показать полную графическую версию : Оперативная память


Malukov.Dmitry
01-12-2018, 09:44
Здравствуйте ! Подскажите пожалуйста, как лучше реализовать сценарий со следующими условиями:

-Нужен сценарий, определяющий количество свободной доступной RAM (x86)
-Выполнение произвольной команды исходя из полученных данных по шаблону:
Если %freeram%>2GB - запускается program.exe и сценарий завершает работу без ожидания завершения выполнения команды
Если %freeram%<2GB - ....
Если %freeram%<1GB - ....
Если %freeram%<512MB -....

Iska
01-12-2018, 10:27
Вас какая «свободная доступная» память интересует — виртуальная или физическая?

Malukov.Dmitry
07-12-2018, 16:35
физическая

Более точнее было бы так:
Если %freeram%>2GB - запускается program.exe и сценарий завершает работу без ожидания завершения выполнения команды
Если %freeram%<2GB, но >1GB - ....
Если %freeram%<1GB, но >512 - ....
Если %freeram%<512MB

Iska
07-12-2018, 18:22
На WSH:
Option Explicit

Dim objSWbemServicesEx
Dim objSWbemObjectEx

Dim lngFreePhysicalMemory


Set objSWbemServicesEx = WScript.CreateObject("WbemScripting.SWbemLocator").ConnectServer(".", "root\cimv2")

For Each objSWbemObjectEx In objSWbemServicesEx.ExecQuery("SELECT FreePhysicalMemory FROM Win32_OperatingSystem")
lngFreePhysicalMemory = CLng(objSWbemObjectEx.FreePhysicalMemory)

If lngFreePhysicalMemory > 2 * 2^20 Then
'Если %freeram%>2GB - запускается program.exe и сценарий завершает работу без ожидания завершения выполнения команды
WScript.CreateObject("WScript.Shell").Run """%SystemRoot%\System32\notepad.exe""", 1, False
ElseIf lngFreePhysicalMemory > 2^20 Then
'Если %freeram%<2GB, но >1GB - ....
'…
ElseIf lngFreePhysicalMemory > 512 * 2^20 Then
'Если %freeram%<1GB, но >512 - ....
'…
Else
'Если %freeram%<512MB
'…
End If

Exit For
Next

Set objSWbemServicesEx = Nothing

WScript.Quit 0

Malukov.Dmitry
07-12-2018, 20:41
в CMD возможно реализовать то же самое ?

Iska
08-12-2018, 02:54
Malukov.Dmitry, для пакетных файлов есть одна проблема: мы не можем напрямую выполнить в них условие:
Если %freeram%>2GB »
поскольку максимальное положительное число, которым напрямую могут оперировать пакетные файлы в арифметических операциях — 2 Gb - 1, а при попытке получить 2 Gb и более — мы получаем дополнение к желаемому:
https://i.imgur.com/oAuScXm.png

megaloman
08-12-2018, 15:07
Malukov.Dmitry, Iska, Подозреваю, wmic os get FreePhysicalMemory,TotalVisibleMemorySize выдаёт память в килобайтах. Тогда, если границы задавать в килобайтах, то:в CMD возможно реализовать то же самое »@Echo Off
cls
Set Program="C:\Windows\System32\notepad.exe"

FOR /F "usebackq skip=1 tokens=1,2 delims= " %%i IN (`"wmic os get FreePhysicalMemory,TotalVisibleMemorySize"`) DO If Not "%%j"=="" Set /A Free=%%i

If %Free% LSS 524288 Call :Lss512Mb %Free% &GoTo :Cont
If %Free% LSS 1048576 Call :Lss1Gb %Free% &GoTo :Cont
If %Free% LSS 2097152 Call :Lss2Gb %Free% &GoTo :Cont
Start " " %Program% &GoTo :Eof
:Cont

pause
GoTo :Eof

:Lss512Mb
Echo 512Mb^<=%1Mb
GoTo :Eof

:Lss1Gb
Echo 512Mb^<=%1Mb^<1Gb
GoTo :Eof

:Lss2Gb
Echo 1Gb^<=%1Mb^<2Gb
GoTo :Eof
Если возможна память >=2000Gb, тоже можно выкрутиться, если wmic отработает, конечно.

Iska
08-12-2018, 18:11
Подозреваю, wmic os get FreePhysicalMemory,TotalVisibleMemorySize выдаёт память в килобайтах. »
В байтах. Так что вижу типичный вариант — отрезать справа, скажем, по три символа, не забывая, что после этого может остаться и пустое место. Для целей коллеги Malukov.Dmitry точности, полагаю, хватит.

Ваша правда — в килобайтах:
FreePhysicalMemory

Data type: uint64

Access type: Read-only

Qualifiers: Units ("kilobytes")

Number, in kilobytes, of physical memory currently unused and available.
Значит, мой предыдущий код некорректен. Сейчас поправим.

Malukov.Dmitry
09-12-2018, 07:06
В принципе, вот к чему пришел. Не самый оптимизированный код, но работает именно как задуманно.
Но опять есть одно НО : уже сломал голову , как прикрутить GUI диалог подтверждения (Да\Нет)в начале сценария.
Интересно VBS может вернуть результат в сценарий, будучу запущенным из сценария же ?

Пробовал Nircmd qbox , но он упорно отказывается понимать команду GOTO, как и не может выполнять команду по нажатию НЕТ (иначе проблема решилась использование банального taskkill хотя бы).

@echo off
title Создание RAM-диска
:Start
IF /i %temp% NEQ X:\windows\temp (goto UnmountRamDiskPromt)

:GetInfo
set RD1=2621440
set RD2=2097152
set RD3=1572864
wmic os get freephysicalmemory>nul
for /f "skip=1" %%p in ('wmic os get freephysicalmemory') do (
set m=%%p
goto RamDiskOpt
)

:RamDiskOpt
Echo Свободной памяти RAM: %m% Килобайт
Echo.
Echo Текущее расположение TEMP: %temp%
Echo Текущее расположение TMP: %tmp%
Echo.
IF /i %m% GEQ %RD1% (
set rdsize=1024
goto getMainFunction
) else (
IF /i %m% GEQ %RD2% (
set rdsize=768
goto getMainFunction
) else (
IF /i %m% GEQ %RD3% (
set rdsize=512
goto getMainFunction
) else (
goto MemoryLow
)
)
)

:MemoryLow
nircmd infobox "Не рекомендуется создавать RAM-диск при объеме свободной памяти менее 1.5 ГБ. Операция будет прервана." "Ошибка"
exit

:getMainFunction
setlocal enabledelayedexpansion
call :getFreeDisk disk
goto MountRamDisk

:getFreeDisk
set cnt=0
for /f "usebackq skip=1 tokens=*" %%A IN (`wmic logicaldisk get caption`) DO (
set /a cnt+=1
set ldisk.!cnt!=%%A
)
set /a cnt-=1
for %%A IN (B K L M N O P Q R S T U V W) DO (
set "f="
for /L %%B IN (1 1 %cnt%) DO (
set "dsk=!ldisk.%%B!"
set "dsk=!dsk:~0,1!"
if /i "%%A"=="!dsk!" (
set "f=1"
)
)
if not defined f (
set %~1=%%~A:
exit /b
)
)
echo>nul
pause
exit

:MountRamDisk
imdisk -a -t vm -s %rdsize%M -m %disk% -p "/fs:ntfs /q /y /v:RAM-Disk">nul
md %disk%\Temp>nul
setx Temp %disk%\Temp>nul
setx Tmp %disk%\Temp>nul
If Exist "%disk%\Temp\" nircmd infobox "Папка TEMP успешно перемещена на диск %disk%." "Готово"&&restartshell
If Not Exist "%disk%\Temp\" nircmd infobox "Не удалось создать RAM-диск или внести изменения в реестр. Будет выбрана папка по умолчанию (X:\windows\Temp)"&&setx temp X:\Windows\Temp&&setx tmp X:\Windows\Temp&&restartshell>nul
exit

:UnmountRamDiskPromt
title Отключение RAM-диска
echo.
Echo Папка TEMP уже перемещена на RAM-диск. Отключить все RAM-диски и установить папку TEMP по умолчанию ?
echo.
Set /p choice="Введите "Y" для продолжения или "N" для выхода и нажмите "ENTER" : "
if not defined choice goto UnmountRamDiskPromt
if "%choice%"=="y" (goto UnmountRamDisk)
if "%choice%"=="Y" (goto UnmountRamDisk)
if "%choice%"=="N" (goto GetInfo)
if "%choice%"=="n" (goto GetInfo)
goto UnmountRamDiskPromt

:UnmountRamDisk
set tmpdir=%temp%
set tmpdisk=%tmpdir:~0,2%
imdisk -d -m %tmpdisk%>nul
setx temp X:\Windows\Temp>nul
setx tmp X:\Windows\Temp>nul
restartshell
nircmd infobox "Все RAM-диски были отключены. Установлена папка TEMP по умолчанию." "Готово"
exit

Iska
09-12-2018, 11:16
Интересно VBS может вернуть результат в сценарий, будучу запущенным из сценария же ? »
Результат — нет, код возврата (он же ErrorLevel) — конечно. Например:
@echo off
setlocal enableextensions enabledelayedexpansion

cscript.exe //nologo "%~dp0Question.vbs" && (
echo Yes
) || (
echo No
)

endlocal
exit /b 0
Option Explicit

WScript.Quit MsgBox( _
"Папка TEMP уже перемещена на RAM-диск." & vbLf & vbLf & _
"Отключить все RAM-диски и установить папку TEMP по умолчанию?", _
vbYesNo + vbQuestion + vbDefaultButton2, _
"Какой-то заголовок") - vbYes

Пробовал Nircmd qbox , но он упорно отказывается понимать команду GOTO, как и не может выполнять команду по нажатию НЕТ »
Вы неправильно понимаете, как это работает. Nircmd.exe/Nircmdc.exe — это внешняя утилита, а не внутренняя команда интерпретатора команд, и она никак не может выполнить внутреннюю «команду GOTO».
qbox [message text] [title] [program to run]
Displays a question dialog-box on the screen. If the user answers "Yes", run a program
Example:
qbox "Do you want to run the calculator ?" "question" "calc.exe"

qboxtop [message text] [title] [program to run]
Similar to qbox, but displays the message-box as top-most window.

qboxcom [message text] [title] [NirCmd Command]
Displays a question dialog-box on the screen. If the user answers "Yes", execute the NirCmd command in the third parameter.
Examples:
qboxcom "Do you want to lock your workstation ?" "question" lockws
qboxcom "Do you want to turn off the monitor ?" "monitor" monitor off

qboxcomtop [message text] [title] [NirCmd Command]
Similar to qboxcom, but displays the message-box as top-most window.

Но к чему всё это? Если пользуете именно консоль — пользуйте choice.exe.

megaloman
09-12-2018, 22:08
Malukov.Dmitry, @Echo Off
cls
Title Создание RAM-диска
Set "Default=X:\windows\temp"

:Start
IF /I Not "%temp%"=="%Default%" Call :UnmountRamDiskPromt ||Exit /B

:GetInfo
Set /A RD1=2621440
Set /A RD2=2097152
Set RD3=1572864

For /f "skip=1" %%p in ('wmic os get freephysicalmemory') Do Set /A m=%%p &GoTo :RamDiskOpt
:RamDiskOpt

Echo Свободной памяти RAM: "%m%" Килобайт
Echo.
Echo Текущее расположение TEMP: %temp%
Echo Текущее расположение TMP: %tmp%
Echo.

If %m% LSS %RD3% (
:MemoryLow
nircmd infobox "Не рекомендуется создавать RAM-диск при объеме свободной памяти менее 1.5 ГБ. Операция будет прервана." "Ошибка"
Exit /B 1
)
Set /A rdsize=512
If %m% GEQ %RD2% Set /A rdsize=768
If %m% GEQ %RD1% Set /A rdsize=1024
Echo Свободно=%m%Kb RAM-диск=%rdsize%

:getFreeDisk
Set "Disks="
For /f "usebackq skip=1 tokens=1,2 Delims=:" %%A IN (`"wmic logicaldisk get caption,name"`) DO If Not "%%B"=="" Call Set "Disks=%%Disks%%%%A"
For %%A IN (B K L M N O P Q R S T U V W) DO (
Echo %Disks%|Find /I "%%A" >nul 2>&1 ||(Set "disk=%%A:" &GoTo :FreeDisk)
)
:FreeDisk
Echo Буква диска=%disk%

:MountRamDisk
imdisk -a -t vm -s %rdsize%M -m %disk% -p "/fs:ntfs /q /y /v:RAM-Disk">nul
md %disk%\Temp>nul
Setx Temp %disk%\Temp>nul
Setx Tmp %disk%\Temp>nul
If Exist "%disk%\Temp\" nircmd infobox "Папка TEMP успешно перемещена на диск %disk%." "Готово"&&restartshell
If Not Exist "%disk%\Temp\" (
nircmd infobox "Не удалось создать RAM-диск или внести изменения в реестр. Будет выбрана папка по умолчанию (%Default%)"
Setx temp "%Default%"
Setx tmp "%Default%
restartshell >nul
)
Pause
GoTo :Eof

:UnmountRamDiskPromt
Title Отключение RAM-диска
Echo.
Echo Папка TEMP уже перемещена на RAM-диск. Отключить все RAM-диски и установить папку TEMP по умолчанию ?
Echo.
Echo ВВедите:
CHOICE /C YN /M "Y-для продолжения, или N-для выхода"

If %ErrorLevel%==2 Exit /B 0

Set tmpdir=%temp%
Set tmpdisk=%tmpdir:~0,2%

imdisk -d -m %tmpdisk%>nul

Setx temp %Default% >nul
Setx tmp %Default%>nul

restartshell
nircmd infobox "Все RAM-диски были отключены. Установлена папка TEMP по умолчанию." "Готово"
Exit /B 2




© OSzone.net 2001-2012