file1.bat:
@echo off
:Test
echo in file one
call file2.bat (Here i want to call only Demo routine in the file2.bat)
Run Code Online (Sandbox Code Playgroud)
file2.bat:
:hello
echo in hello
:Demo
echo in Demo
Run Code Online (Sandbox Code Playgroud)
我想从批处理文件1中调用批处理文件2中的子例程。
我尝试了例如,call file2.bat:Demo
但是没有给出正确的结果。
我该如何实现?
带有子程序的文件必须如下所示:
@echo off
call :%*
exit /b %errorlevel%
:hello
echo in hello
exit /b 0
:Demo
echo in Demo with argument %1
exit /b 0
Run Code Online (Sandbox Code Playgroud)
然后从另一个文件中,您可以像这样称呼它
call file2.bat demo "arg-one"
Run Code Online (Sandbox Code Playgroud)
您可以将函数文件(在此示例中为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
Run Code Online (Sandbox Code Playgroud)
然后,呼叫者批次可以像
@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
Run Code Online (Sandbox Code Playgroud)
在这种情况下,需要在两个文件中使用相同的名称定义标签。
直接调用“库”批处理文件将替换的上下文call :label
,并且在读取所调用的批处理时,将goto :label
在内部执行a并在指示的标签内继续执行代码。当被调用的批处理文件结束时,将释放上下文,并call :label
继续执行之后的代码。
已编辑
正如Jeb在评论中指出的那样,这种方法有一个缺点。在被调用的批处理文件中运行的代码不能用于%0
检索被调用函数的名称,它将返回该批处理文件的名称。但是,如果需要,调用者可以按照示例代码中所示进行操作。
编辑2016/12/27
回答dbenham,我无法知道这是编码错误还是预期的功能,但这是该过程的工作方式
BatLoop
创建批处理“上下文”时,批处理文件中的行将在内部函数中进行处理。此函数作为其参数之一接收指向导致创建“上下文”的命令的指针。
在此功能内,批处理文件中的命令被迭代。遍历命令的循环在每次迭代中进行测试:如果启用了扩展,则它是批处理文件中的第一行,并且启动上下文的命令的参数以冒号(标签)开头,将goto
生成一个跳转到标签。
到这里为止,我必须假设这是处理call :label
语法的预期行为:创建一个新的“上下文”,加载文件,跳转到标签。
但是收到的命令参数永远不会改变,使用另一个变量来跟踪批处理文件中命令的执行。如果将新的批处理文件加载到/覆盖当前的批处理“上下文”(我们尚未使用call
命令),则在加载新的批处理代码后,将BatLoop
重置行数(我们从已加载文件的第一行开始),瞧,则循环开始处的条件(允许扩展,第一行,冒号)再次为真(指向的输入命令尚未更改),并goto
生成新的条件。