2015-05-11 2 views
3

file1.bat:Вызов подпрограммы в пакете из другого пакетного файла

@echo off 
:Test 
echo in file one 
call file2.bat (Here i want to call only Demo routine in the file2.bat) 

file2.bat:

:hello 
echo in hello 
:Demo 
echo in Demo 

Из партии file1 Я хочу, чтобы позвонить в подпрограмму в пакетный файл2.
Я попытался, например, call file2.bat:Demo, но это не дало правильного результата.

Как я могу это достичь?

ответ

3

файл с подпрограммами должен выглядеть следующим образом:

@echo off 
call :%* 
exit /b %errorlevel% 

:hello 
echo in hello 
exit /b 0 
:Demo 
echo in Demo with argument %1 
exit /b 0 

затем из другого файла, который вы можете назвать это как

call file2.bat demo "arg-one" 
+0

Вы прочитали ответ MCND? Думаю, вам нравятся такие трюки или вы уже это знаете? – jeb

+0

@jeb - отличный трюк !! – npocmaka

+0

это выглядит чище для меня –

4

Вы можете написать функции файл (в данном примере это 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.

+1

Мне нравится этот трюк, есть только один маленький _drawback_, в вызываемой функции во вторичной партии '% 0' не содержится имя функции, в котором содержится имя командного файла, но поскольку почти никто не использует'% 0' для извлечения текущего название функции это действительно небольшая разница – jeb

+0

потрясающий! :-) .... – npocmaka

+0

@jeb, конечно, вы правы. Размышляя о возможности того, что кому-то может понадобиться имя функции, в представленном коде кода был включен «echo», получая имя функции перед передачей остальной части работы в «библиотеку». Теперь он включен в ответ, спасибо. –

Смежные вопросы