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
From the batch file1 I want to make a call to a sub routine in the batch file2.
I tried for example call file2.bat:Demo
but it didn't give the correct result.
从批处理文件1我想调用批处理文件2中的子例程。我试过例如调用file2.bat:Demo但它没有给出正确的结果。
How I can achieve this?
我怎么能做到这一点?
2 个解决方案
#1
the file with subroutines must look like:
子程序的文件必须如下所示:
@echo off
call :%*
exit /b %errorlevel%
:hello
echo in hello
exit /b 0
:Demo
echo in Demo with argument %1
exit /b 0
then from the other file you can call it like
然后从另一个文件中你可以称之为
call file2.bat demo "arg-one"
#2
You can write your functions file (in this sample it is library.cmd
) as
您可以将函数文件(在此示例中为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
And then the caller batch can be something like
然后调用者批处理就像这样
@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
In this case, the labels need to be defined with the same name in both files.
在这种情况下,需要在两个文件中使用相同的名称定义标签。
The direct invocation of the "library" batch file will replace the context of the call :label
, and when the invoked batch is readed, a goto :label
is internally executed and code continues inside the indicated label. When the called batch file ends, the context is released and the code after the call :label
continues.
直接调用“库”批处理文件将替换call:label的上下文,并且当调用调用的批处理时,goto:标签在内部执行,代码在指定的标签内继续。当被调用的批处理文件结束时,将释放上下文并且调用后的代码:标签继续。
edited
As Jeb points in comments, there is a drawback in this method. The code running in the called batch file can not use %0
to retrieve the name of the function being called, it will return the name of the batch file. But if needed, the caller can do it as shown in the sample code.
正如杰布在评论中指出的那样,这种方法存在缺陷。在被调用批处理文件中运行的代码不能使用%0来检索被调用函数的名称,它将返回批处理文件的名称。但是如果需要,调用者可以执行它,如示例代码所示。
edited 2016/12/27
Answering to dbenham, I have no way to know if it was a coding error or an intended feature, but this is how the process works
回答dbenham,我无法知道它是编码错误还是预期的功能,但这是过程的工作原理
The lines in batch file are processed inside the inner BatLoop
function when a batch "context" is created. This function receives, as one of its arguments, a pointer to the command that caused the "context" to be created.
批处理“上下文”创建时,批处理文件中的行将在内部BatLoop函数内处理。该函数接收指向导致创建“上下文”的命令的指针,作为其参数之一。
Inside this function the commands in the batch file are iterated. The loop that iterates over the commands makes a test in each iteration: if extensions are enabled, it is the first line in the batch file and the arguments of the command that started the context starts with a colon (a label), a goto
is generated to jump to the label.
在此函数内,迭代批处理文件中的命令。循环遍历命令的循环在每次迭代中进行测试:如果启用了扩展,则它是批处理文件中的第一行,并且启动上下文的命令的参数以冒号(标签)开头,goto是生成跳转到标签。
Up to here, I have to suppose that this is the intended behaviour to handle the call :label
syntax: create a new "context", load the file, jump to the label.
到目前为止,我不得不假设这是处理调用的预期行为:标签语法:创建一个新的“上下文”,加载文件,跳转到标签。
But the command argument received is never changed, a different variable is used to track the execution of the commands in the batch file. If a new batch file is loaded into / overwrites the current batch "context" (we have not used call
command), after loading the new batch code, BatLoop
resets the line count (we start at the first line of the loaded file) and, voila, the condition at the start of the loop (extensions enabled, first line, the colon) is true again (the pointed input command has not been changed) and a new goto
is generated.
但是收到的命令参数永远不会改变,不同的变量用于跟踪批处理文件中命令的执行。如果新批处理文件被加载到/覆盖当前批处理“上下文”(我们没有使用调用命令),则在加载新的批处理代码后,BatLoop会重置行计数(我们从加载文件的第一行开始)和,瞧,循环开始时的条件(扩展已启用,第一行,冒号)再次为真(指向的输入命令尚未更改)并生成新的goto。
#1
the file with subroutines must look like:
子程序的文件必须如下所示:
@echo off
call :%*
exit /b %errorlevel%
:hello
echo in hello
exit /b 0
:Demo
echo in Demo with argument %1
exit /b 0
then from the other file you can call it like
然后从另一个文件中你可以称之为
call file2.bat demo "arg-one"
#2
You can write your functions file (in this sample it is library.cmd
) as
您可以将函数文件(在此示例中为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
And then the caller batch can be something like
然后调用者批处理就像这样
@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
In this case, the labels need to be defined with the same name in both files.
在这种情况下,需要在两个文件中使用相同的名称定义标签。
The direct invocation of the "library" batch file will replace the context of the call :label
, and when the invoked batch is readed, a goto :label
is internally executed and code continues inside the indicated label. When the called batch file ends, the context is released and the code after the call :label
continues.
直接调用“库”批处理文件将替换call:label的上下文,并且当调用调用的批处理时,goto:标签在内部执行,代码在指定的标签内继续。当被调用的批处理文件结束时,将释放上下文并且调用后的代码:标签继续。
edited
As Jeb points in comments, there is a drawback in this method. The code running in the called batch file can not use %0
to retrieve the name of the function being called, it will return the name of the batch file. But if needed, the caller can do it as shown in the sample code.
正如杰布在评论中指出的那样,这种方法存在缺陷。在被调用批处理文件中运行的代码不能使用%0来检索被调用函数的名称,它将返回批处理文件的名称。但是如果需要,调用者可以执行它,如示例代码所示。
edited 2016/12/27
Answering to dbenham, I have no way to know if it was a coding error or an intended feature, but this is how the process works
回答dbenham,我无法知道它是编码错误还是预期的功能,但这是过程的工作原理
The lines in batch file are processed inside the inner BatLoop
function when a batch "context" is created. This function receives, as one of its arguments, a pointer to the command that caused the "context" to be created.
批处理“上下文”创建时,批处理文件中的行将在内部BatLoop函数内处理。该函数接收指向导致创建“上下文”的命令的指针,作为其参数之一。
Inside this function the commands in the batch file are iterated. The loop that iterates over the commands makes a test in each iteration: if extensions are enabled, it is the first line in the batch file and the arguments of the command that started the context starts with a colon (a label), a goto
is generated to jump to the label.
在此函数内,迭代批处理文件中的命令。循环遍历命令的循环在每次迭代中进行测试:如果启用了扩展,则它是批处理文件中的第一行,并且启动上下文的命令的参数以冒号(标签)开头,goto是生成跳转到标签。
Up to here, I have to suppose that this is the intended behaviour to handle the call :label
syntax: create a new "context", load the file, jump to the label.
到目前为止,我不得不假设这是处理调用的预期行为:标签语法:创建一个新的“上下文”,加载文件,跳转到标签。
But the command argument received is never changed, a different variable is used to track the execution of the commands in the batch file. If a new batch file is loaded into / overwrites the current batch "context" (we have not used call
command), after loading the new batch code, BatLoop
resets the line count (we start at the first line of the loaded file) and, voila, the condition at the start of the loop (extensions enabled, first line, the colon) is true again (the pointed input command has not been changed) and a new goto
is generated.
但是收到的命令参数永远不会改变,不同的变量用于跟踪批处理文件中命令的执行。如果新批处理文件被加载到/覆盖当前批处理“上下文”(我们没有使用调用命令),则在加载新的批处理代码后,BatLoop会重置行计数(我们从加载文件的第一行开始)和,瞧,循环开始时的条件(扩展已启用,第一行,冒号)再次为真(指向的输入命令尚未更改)并生成新的goto。