Вы можете написать функции файл (в данном примере это library.cmd
) в
@echo off
setlocal enableextensions
rem Not to be directly called
exit /b 9009
:test
echo test [%*]
goto :eof
:test2
echo test2 [%*]
goto :eof
:testErrorlevel
echo testErrorlevel
exit /b 1
И тогда партия абонент может быть что-то вроде
@echo off
setlocal enableextensions disabledelayedexpansion
call :test arg1 arg2 arg3
call :test2 arg4 arg5 arg6
call :testErrorlevel && echo no errorlevel || echo errorlevel raised
goto :eof
:test
:test2
echo calling function %0
library.cmd %*
:testErrorlevel
echo calling function %0
library.cmd
В этом случае метки должны быть определены с одинаковым именем в обоих файлах.
Прямой вызов командного файла «library» заменит контекст call :label
, и когда запрошенная партия будет считана, goto :label
будет выполнен внутренним образом, а код продолжен внутри указанной метки. Когда вызываемый пакетный файл заканчивается, контекст освобождается, и код после call :label
продолжается.
отредактировал
Как Джеб указывает в комментариях, есть недостаток в этом методе. Код, запущенный в вызываемом пакетном файле, не может использовать %0
для извлечения имени вызываемой функции, он вернет имя командного файла. Но при необходимости вызывающий может сделать это, как показано в примере кода.
отредактировал 2016/12/27
Отвечая на dbenham, у меня нет никакого способа узнать, если это была ошибка кодирования или намеренное особенность, но это то, как процесс работает
Линии в пакетном файле обрабатываются внутри внутренней функции BatLoop
, когда создается пакетный «контекст». Эта функция получает в качестве одного из своих аргументов указатель на команду, которая вызвала создание «контекста».
Внутри этой функции команды в пакетном файле повторяются. Цикл, который выполняет итерации над командами, делает тест на каждой итерации: если расширения включены, это первая строка в командном файле, а аргументы команды, запускающей контекст, начинаются с двоеточия (метка), goto
- сгенерированный для перехода к метке.
До сих пор я должен предположить, что это предназначенное поведение для обработки синтаксиса call :label
: создать новый «контекст», загрузить файл, перейти к метке.
Но полученный аргумент команды никогда не изменяется, для отслеживания выполнения команд из командного файла используется другая переменная. Если новый пакетный файл загружается в/перезаписывает текущий пакетный «контекст» (мы не использовали команду call
), после загрузки нового пакетного кода BatLoop
сбрасывает количество строк (мы начинаем с первой строки загруженного файла) и , voila, условие в начале цикла (расширения включены, первая строка, двоеточие) снова истинно (команда отмеченного ввода не была изменена) и генерируется новый goto
.
Вы прочитали ответ MCND? Думаю, вам нравятся такие трюки или вы уже это знаете? – jeb
@jeb - отличный трюк !! – npocmaka
это выглядит чище для меня –