Операторы if для обработки определенного числового значения переменной всегда попадают в последний оператор if, независимо от значения переменной

Я хочу обрабатывать разные функции в зависимости от общего объема оперативной памяти ПК.

Для этого я придумал эту функцию:

:function.texture_streaming
setlocal EnableDelayedExpansion
for /f "usebackq tokens=*" %%a in (
    `PowerShell -Command "(Get-WmiObject Win32_PhysicalMemory | Measure Capacity -Sum).Sum/1GB"`
) do (
    set "ram=%%a"
)
if "%ram%" lss "16" (
    call :error.insufficient_ram "!ram!"
    endlocal
    goto :prompt.performance
)
if "%ram%" geq "16" if "%ram%" lss "32" (
    call :subroutine.limited_texture_streaming
    endlocal
    goto :prompt.performance
)
if "%ram%" geq "32" (
    call :subroutine.full_texture_streaming
    endlocal
    goto :prompt.performance
    )
endlocal
goto :prompt.performance

Моя проблема в том, что независимо от значения %ram% всегда обрабатывается последний оператор if. Даже если я установлю значение %ram% на 8 вручную, он все равно обработает последний оператор if, когда мне нужно обработать первый. Я также перенаправил значение %ram% в текстовый файл, чтобы проверить, есть ли пробелы, но их нет.

Пожалуйста, прочитайте мой ответ на Символ, эквивалентный NEQ, LSS, GTR и т. д. в пакетных файлах Windows. Использование " в условии IF всегда приводит к сравнению строк, а не к целочисленному сравнению, как вам хотелось бы. Используйте if %ram% LSS 16, if %ram% GEQ 16 if %ram% LSS 32 и if %ram% GEQ 32. Следует убедиться, что с помощью set "ram = " вверху и if not defined ram goto :EOF после цикла FOR /F необходимо убедиться, что эта переменная среды вообще может быть успешно определена с помощью 32-битного целочисленного значения со знаком.

Mofi 16.08.2024 12:00

Еще несколько предложений: замените весь командный блок for /f одной командной строкой for /F %%I in ('%SystemRoot%\System32\WindowsPowerShell\v1.0\powershell.ex‌​e -NoLogo -NoProfile -Command "(Get-WmiObject Win32_PhysicalMemory | Measure Capacity -Sum).Sum/1GB"') do set "ram=%%I". Расширение отложенной переменной вообще не требуется. Замените setlocal EnableDelayedExpansion на setlocal EnableExtensions DisableDelayedExpansion или удалите эту строку и все endlocal и, конечно же, замените call :error.insufficient_ram "!ram!" на call :error.insufficient_ram "%ram%".

Mofi 16.08.2024 12:08

Я бы посоветовал вам изменить команду, чтобы использовать командлет CIM, а не WMI. Вот без сокращений: For /F %%G In ('%SystemRoot%\System32\WindowsPowerShell\v1.0\powershell.ex‌​e -NoLogo -NoProfile -Command "(Get-CimInstance Cim_PhysicalMemory | Measure-Object -Property Capacity -Sum).Sum / 1GB" 2^>NUL') Do Set "ram=%%G".

Compo 16.08.2024 13:12

@Mofi Я прочитал упомянутый вами ответ и соответствующим образом скорректировал другие части моего сценария. Я не знал, что equ отличается от ==. Я также исключил из кавычек переменную и целочисленное значение в каждом операторе if, и это помогло! @Compo Я перешел на CIM вместо WMI, как вы предлагали. Спасибо вам обоим за ваши предложения и помощь.

leiseg 16.08.2024 15:06
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
0
4
79
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

На самом деле вам не требуется установка переменной, вам не нужны все внутренние круглые скобки и не требуется delayedexpansion.

Вы можете просто выполнить поиск, используя метапеременную %%a.

:function.texture_streaming
for /f "delims = " %%a in ('PowerShell -Command "(Get-WmiObject Win32_PhysicalMemory | Measure Capacity -Sum).Sum/1GB"') do (
         if %%a lss 16 call :error.insufficient_ram %%a

         if %%a geq 16 if %%a lss 32 call :subroutine.limited_texture_streaming

         if %%a geq 32 call :subroutine.full_texture_streaming
         goto :prompt.performance
    )

Кроме того, вам не нужен goto :prompt.performance после каждого оператора if, так как все несовпадающие операторы if будут провалены и все они достигнут goto после последнего if.

Герхард, возможно, вы и правы насчет использования отложенного раскрытия, но вполне возможно, что оно требуется где-то в неопубликованных разделах с пометками :error.insufficient_ram, :subroutine.limited_texture_streaming и :subroutine.full_texture_streaming.

Compo 16.08.2024 22:48

Это действительно возможно, @Compo, но я почти уверен, что OP установил отложенное расширение из-за расширения, необходимого для переменной !ram! в цикле for. Однако ОП может добавить его обратно, если это необходимо.

Gerhard 17.08.2024 07:48
Ответ принят как подходящий

Благодаря @Mofi и @Compo мне удалось решить проблему.

Это теперь работающий код:

setlocal

rem Initialize variable.

set "ram = "

for /f "usebackq tokens=*" %%a in (

    `PowerShell -NoLogo -NoProfile -Command "(Get-CIMInstance CIM_PhysicalMemory | Measure-Object -Property Capacity -Sum).Sum / 1GB"`

) do (

    set "ram=%%a"

)

if not defined ram (

    call :error.function_failed "determining your total RAM capacity"

    endlocal

    goto :prompt.performance

)

if %ram% lss 16 (

    pause

    call :error.insufficient_ram "%ram%"

    endlocal

    goto :prompt.performance

)

if %ram% geq 16 if %ram% lss 32 (

    call :subroutine.limited_texture_streaming

    endlocal

    goto :prompt.performance

)

if  %ram% geq 32 (

    call :subroutine.full_texture_streaming

    endlocal

    goto :prompt.performance
    
)

endlocal

goto :prompt.performance

Другие вопросы по теме