Компьютерный форум OSzone.net  

Компьютерный форум OSzone.net (http://forum.oszone.net/index.php)
-   Скриптовые языки администрирования Windows (http://forum.oszone.net/forumdisplay.php?f=102)
-   -   Оперативная память (http://forum.oszone.net/showthread.php?t=337986)

Malukov.Dmitry 01-12-2018 09:44 2843519

Оперативная память
 
Здравствуйте ! Подскажите пожалуйста, как лучше реализовать сценарий со следующими условиями:

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

Iska 01-12-2018 10:27 2843522

Вас какая «свободная доступная» память интересует — виртуальная или физическая?

Malukov.Dmitry 07-12-2018 16:35 2844701

физическая

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

Iska 07-12-2018 18:22 2844720

На 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 2844754

в CMD возможно реализовать то же самое ?

Iska 08-12-2018 02:54 2844791

Malukov.Dmitry, для пакетных файлов есть одна проблема: мы не можем напрямую выполнить в них условие:
Цитата:

Цитата Malukov.Dmitry
Если %freeram%>2GB »

поскольку максимальное положительное число, которым напрямую могут оперировать пакетные файлы в арифметических операциях — 2 Gb - 1, а при попытке получить 2 Gb и более — мы получаем дополнение к желаемому:

megaloman 08-12-2018 15:07 2844845

Malukov.Dmitry, Iska, Подозреваю, wmic os get FreePhysicalMemory,TotalVisibleMemorySize выдаёт память в килобайтах. Тогда, если границы задавать в килобайтах, то:
Цитата:

Цитата Malukov.Dmitry
в 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 2844867

Цитата:

Цитата megaloman
Подозреваю, 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 2844967

В принципе, вот к чему пришел. Не самый оптимизированный код, но работает именно как задуманно.
Но опять есть одно НО : уже сломал голову , как прикрутить 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 2844981

Цитата:

Цитата Malukov.Dmitry
Интересно VBS может вернуть результат в сценарий, будучу запущенным из сценария же ? »

Результат — нет, код возврата (он же ErrorLevel) — конечно. Например:
Sample.cmd
Код:

@echo off
setlocal enableextensions enabledelayedexpansion

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

endlocal
exit /b 0

Question.vbs
Код:

Option Explicit

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


Цитата:

Цитата Malukov.Dmitry
Пробовал Nircmd qbox , но он упорно отказывается понимать команду GOTO, как и не может выполнять команду по нажатию НЕТ »

Вы неправильно понимаете, как это работает. Nircmd.exe/Nircmdc.exe — это внешняя утилита, а не внутренняя команда интерпретатора команд, и она никак не может выполнить внутреннюю «команду GOTO».
Nircmd Help
Цитата:

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 2845070

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



Время: 18:17.

Время: 18:17.
© OSzone.net 2001-