Один из способов - работать с отложенным расширением внутри пакета, потому что тогда специальные символы теряют там «особые» значения.
Единственная проблема - получить параметры в переменной.
Как-то так может помочь
@echo off
setlocal DisableDelayedExpansion
rem ** At this point the delayedExpansion should be disabled
rem ** otherwise an exclamation mark in %1 can remove carets
set "param1=%~1"
setlocal EnableDelayedExpansion
rem ** Now you can use the param1, independent of the content, even with carets or quotes
rem ** but be careful with call's, because they start a second round of expansion
echo !param1!
set "tmp=!param1:~1,4!"
Теперь параметры могут быть заключены в кавычки, так что каретки больше не нужны.Пример launcher.bat "abc> def & geh% ijk | lmn ^ opq!"
Единственным оставшимся проблемным специальным символом, кажется, является кавычка.
[Редактировать / улучшить] Iсоздайте другой способ получения параметра, я предполагаю, что он может принять любую строку и ваш второй пример.
Даже очень сложные строки, такие как
launcher "^
launcher ten ^> one
launcher "&" ^ &
@echo off
setlocal DisableDelayedExpansion
set "prompt=X"
for %%a in (1 ) do (
@echo on
for %%b in (4) do (
rem #%1#
)
) > XY.txt
@echo off
for /F "delims=" %%a in (xy.txt) DO (
set "param=%%a"
)
setlocal EnableDelayedExpansion
set param=!param:~7,-4!
echo param='!param!'
Как это работает?
Единственный способ найти% 1 без расширения специальных символов, таких как "или ^, - это оператор REM (для REMэто не совсем верно, но это другая история) Хорошо, единственная проблема в том, что REM является замечанием и не имеет никакого эффекта :-)
Но если вы используете echo на такжеСтроки rem выводятся перед выполнением (выполнить для rem - хорошее слово).
Следующая проблема заключается в том, что она отображается, и вы не можете перенаправить этот отладочный вывод с помощью обычного> debug.txt,Это также верно, если вы используете цикл for.
Хорошо, вы можете перенаправить эхо-сигнал на с помощью вызова, подобного
echo on
call :myFunc > debug.txt
Но если вы вызываете функцию, вы не можете получить доступ к% 1пакетный файл больше.
Но с двойным циклом for можно активировать перенаправление для вывода отладки, и все еще можно получить доступ к% 1.
Я изменяю приглашение на «X», так что я знаю этодлина всего одного символа.
Осталось только объяснить, почему я добавляю # к% 1.
Это потому, что некоторые специальные символы распознаются в некоторых ситуациях даже в строке REM, очевидно;-)
rem This is a remark^
rem This_is_a_multiline^
rem "This is also a multiline"^
Таким образом, # подавляет возможную многострочную ситуацию.