Предисловие
Я новичок в партии и делаю это около 2 недель. Моя функция не соответствует тому, что я считаю нормальными правилами выполнения программ, когда я добавляю в нее определенный цикл for. Когда цикл for удален, функция следует ожидаемому потоку программ, но вывод все равно не тот, который я хочу. Основная проблема - это переменные с отложенным расширением внутри переменных с отложенным расширением.
Я проверял скобки несколько раз и не могу найти ничего несбалансированного в них в полном коде внизу. С точки зрения выполнения программы это не имеет смысла, добавление цикла for влияет на операторы перед циклом for. Единственное, о чем я могу думать, это то, что происходит странная ошибка, когда код просто не выполняет полный цикл и достигает моего оператора pause сразу после цикла.
Что я на самом деле пытаюсь сделать
Я пытаюсь разграничить строку на одну строку; с неизвестным / переменным числом токенов и другими возможными разделителями в строке (например, запятыми), которые я хочу разделить ПОЗЖЕ. Этого нельзя сделать с помощью циклов for, которые были подготовлены пакетным способом, FOR / F может одновременно выполнять только строки и / или устанавливать количество токенов, а также регулярные значения для разделителей цикла с помощью точек с запятой и запятых. Я хочу разделить ПЕРВЫЙ точкой с запятой, а затем запятыми позже по отдельности. Для этого я пытаюсь сделать свой собственный простой разделитель строки для цикла с метками. Я столкнулся с проблемой, связанной с отложенным расширением моих переменных. Пример здесь:
Не полный код, но код до проблемы с отложенным расширением
setlocal EnableDelayedExpansion
set "TestArgument=%~1"
set /a "CurrentIndex=0"
set /a "DelimIndex=0"
set /a "LoopCount=0"
:ForEach
IF "!TestArgument:~%CurrentIndex%,1!"=="" (goto :ForEachEnd & echo End of list)
echo testing semicolon
IF NOT "!TestArgument:~%CurrentIndex%,1!"==";" (SET /a CurrentIndex=%CurrentIndex%+1 & goto :ForEach & echo found non ;) ELSE (
set /a "LengthToSearch=%CurrentIndex%-%DelimIndex%"
SET "currentArg=!TestArgument:~%DelimIndex%,!LengthToSearch!!
Что я хочу от этой конкретной части функции
Пример ввода:
set "ICMPv4RuleTest="Enable Echo Ping Request ICMPv4;Protocol,ICMPv4;Enabled,Yes;LocalIP,Any;RemoteIP,Any;Direction,In;Action,Allow""
Пример желаемых выходных данных: цикл For (метки выше), где каждая итерация принимает одну строку, разделенную; поэтому первая итерация будет принимать значение Enable Echo Ping Request ICMPv4
. Весь смысл вышеизложенного состоит в том, чтобы взять входные данные и подстроку таким образом, чтобы каждая итерация была разделена точкой с запятой
Приведенный выше код, в частности, последняя строка, вызывает проблему, потому что (я думаю) программа считывает это как увеличение задержки !TestArgument:~%DelimIndex%,!
(что приведет к ошибке)! (что ничто), оставляя только LengthToSearch в виде необработанной строки. Я хочу, чтобы значение LengthToSearch было раскрыто перед операцией подстроки, затем разверните / запустите / выполните расширение операции подстроки и установите для нее значение CurrentArg (строка из одной строки, разделенная символом;). Я не могу использовать знаки% с LengthtoSearch, так как он, похоже, находится в той же области действия, что и операция подстроки, однако я могу использовать знаки% с DelimIndex (потому что это выходит за рамки? Я не знаю).
Что я пробовал
Я пробовал варианты строки подстроки (последняя строка), включая:
SET "currentArg=!TestArgument:~%DelimIndex%,%LengthToSearch%!
ничего не печатает.
SET "currentArg=!TestArgument:~%DelimIndex%,!!LengthToSearch!!!
печатает 31 (буквальный аргумент DelimIndex).
SET "currentArg=%TestArgument:~%DelimIndex%,!!LengthToSearch!!%
ничего не печатает.
SET "currentArg=%TestArgument:~%DelimIndex%,!LengthToSearch!%
ничего не печатает.
Я пробовал некоторые другие, но они определенно не правы. Я думаю, что так и должно было быть
SET "currentArg=!TestArgument:~%DelimIndex%,!LengthToSearch!!
.
Кстати, но это как раз имеет вышеупомянутые проблемы. Я провел здесь некоторое исследование и обнаружил, что у кого-то еще есть нечто похожее на мою проблему с поиском и заменой строк, и они использовали цикл FOR для вставки значений отложенного раскрытия в операцию подстроки отложенного раскрытия в качестве параметра цикла for. Я думал, что смогу использовать ту же методологию, поэтому я попробовал это (большое изменение в последней строке):
setlocal EnableDelayedExpansion
set "TestArgument=%~1"
set /a "CurrentIndex=0"
set /a "DelimIndex=0"
set /a "LoopCount=0"
:ForEach
IF "!TestArgument:~%CurrentIndex%,1!"=="" (goto :ForEachEnd & echo End of list)
echo testing semicolon
IF NOT "!TestArgument:~%CurrentIndex%,1!"==";" (SET /a CurrentIndex=%CurrentIndex%+1 & goto :ForEach & echo found non ;) ELSE (
set /a "LengthToSearch=%CurrentIndex%-%DelimIndex%"
FOR /F "tokens=*" %%A IN ("!LengthToSearch!") DO (SET "currentArg=!TestArgument:~%DelimIndex%,%%A!)
И вот, когда все стало действительно странным. По какой-то причине добавление forloop приводит к тому, что весь случай ELSE не выполняется. Когда я запускаю свой код,
IF NOT "!TestArgument:~%CurrentIndex%,1!"==";"
Только «запускается» один раз (он на самом деле не запускает все, что должен), и тогда цикл буквально прерывается. Я не имею в виду, что он подходит к концу цикла, он просто полностью игнорирует всю остальную функцию. Я проверял скобки несколько раз в полном коде ЗДЕСЬ:
Полный код функции
:FirewallRuleTestFunc
echo got to function
setlocal EnableDelayedExpansion
set "TestArgument=%~1"
ECHO PARAM WAS "%~1"
echo TestArgument was "%TestArgument%"
set /a "CurrentIndex=0"
set /a "DelimIndex=0"
set /a "LoopCount=0"
echo trying foreach
:ForEach
echo got to foreach
IF "!TestArgument:~%CurrentIndex%,1!"=="" (goto :ForEachEnd & echo End of list)
echo testing semicolon
IF NOT "!TestArgument:~%CurrentIndex%,1!"==";" (SET /a CurrentIndex=%CurrentIndex%+1 & goto :ForEach & echo found non ;) ELSE (
echo WHY IS THIS NOT BEING REACHED.
echo CurrentIndex is %CurrentIndex%
echo startposition was first: %DelimIndex%
set /a "LengthToSearch=%CurrentIndex%-%DelimIndex%"
echo length to search was: !LengthToSearch!
echo length to search was: %LengthToSearch%
echo startposition was: %DelimIndex%
FOR /F "tokens=*" %%A IN ("!LengthToSearch!") DO (SET "currentArg=!TestArgument:~%DelimIndex%,%%A!)
echo loop of ; Arg was: !currentArg!
set /a DelimIndex=!CurrentIndex!
echo Delim index was: %DelimIndex%
IF !LoopCount! NEQ 0 (
echo afterfirstloop
FOR /F "tokens=1,2 delims=," %%A IN ('netsh advfirewall firewall show rule name^="!RuleName!" ^| FIND "%%A"') DO (
echo loop of , A was '%%A'
SET "FoundArgument=%%B"
SET "FirewallRuleExists=%%A"
IF "!FirewallRuleExists!"=="" (echo TEST FAILED firewall rule with name "!RuleName!" NOT FOUND)
IF "!FoundArgument!"=="Yes" (echo Test Passed) ELSE (echo Test Failed was "!FoundArgument!")
)
) ELSE (SET "RuleName=!currentArg!" & set /a "LoopCount=%LoopCount%+1" & echo firstloop done)
echo got past if else
)
:ForEachEnd
echo end of THING
endlocal
echo SOMETHING
goto:EOF
И никакого эха ни в случае ELSE второго IF (IF NOT "!TestArgument:~%CurrentIndex%,1!"==";"
), ни в любом другом эхо, кроме тех, что были до второго IF, вообще не было. Это абсолютно бессмысленно для меня, и я не могу понять, почему он игнорирует поток программы, когда добавляется цикл for, и поток программы работает, когда цикл for закомментирован. Все, что я хочу сделать, это иметь цикл for, который повторяется один раз для каждого разделителя, который я могу указать. Мое единственное предположение, что произошла какая-то ошибка, заставляющая его перейти непосредственно к EOF. сразу после вызова моей функции наступает пауза, потому что остальная часть моей программы не имеет значения. И я сейчас работаю только над этой частью. Входные данные для функции указаны ниже:
Пример вызова функции:
set "ICMPv4RuleTest="Enable Echo Ping Request ICMPv4;Protocol,ICMPv4;Enabled,Yes;LocalIP,Any;RemoteIP,Any;Direction,In;Action,Allow""
call :FirewallRuleTestFunc %ICMPv4RuleTest%
Я очень расстроен и мне просто нужна помощь. Я буду продолжать пробовать разные вещи, но это последняя часть моей программы, которую я должен завершить, и я просто хочу получить что-то стабильное, работающее и эффективное, и мне не нужно делать то, что я делал ранее, используйте линейные столбцы и магические числа для проверки настройки брандмауэра по токену. (Я тестирую скрипт для настройки некоторых параметров, чтобы можно было настроить сеть компании).