有几种方法或技巧可以做到这一点。在这个解决方案中,诀窍在于将正在运行的程序的上下文更改为第二个批处理文件。在此更改之后,第二个批处理文件中的所有标签都成为正在运行的程序的本地标签,因此可以通过通常的call :label
命令直接调用它们,也可以以完全标准的方式包含参数。运行程序的上下文必须在程序终止之前恢复。
更改上下文组成的方法是将第二个批处理文件重命名为与第一个相同的名称(并将第一个重命名为任何其他名称),因此当批处理文件处理器查找标签时,它实际上会搜索内容第二个文件!在程序终止之前,必须将文件重命名回其原始名称。使该方法起作用的关键在于,两组重命名命令(以及它们之间的所有代码)都必须用括号括起来;这样,代码是先解析后从内存中执行的,所以磁盘上文件的重命名不影响它。当然,这意味着对代码中所有变量的值的访问必须通过延迟!扩展!(或使用call %%variable%%
技巧)。
第一个.bat
@echo off
rem Change the running context to the second/library batch file:
(
ren first.bat temporary.bat
ren second.bat first.bat
rem From this point on, you may call any label in second.bat like if it was a local label
call :label2
echo Returned from :label2
call :label1
echo Returned from :label1
rem Recover the running context to the original batch file
ren first.bat second.bat
ren temporary.bat first.bat
)
echo This is first.bat ending...
pause > nul
二.bat
@echo off
:label1
echo I am label1 subroutine at second.bat
goto :EOF
:label2
echo This is the second subroutine at second.bat
goto :EOF
输出
This is the second subroutine at second.bat
Returned from :label2
I am label1 subroutine at second.bat
Returned from :label1
This is first.bat ending...
您应该注意,此方法允许以通常的方式开发第一个文件中的子例程(无需更改上下文),然后只需将完成的子例程移动到第二个/库文件,因为调用它们的方式完全相同两种情况。这种方法不需要对第二个/库文件进行任何更改,也不需要对子程序的调用方式进行任何更改;它只需要在第一个文件中插入两个小块的重命名命令。
编辑:发生运行时错误时恢复文件
如评论中所述,如果在重命名文件后发生运行时错误,则不会将文件重命名回其原始名称;但是,通过 second.bat 文件的存在很容易检测到这种情况,如果这样的文件不存在,则恢复文件。这个测试可以在一个在单独的 cmd.exe 上下文中运行原始代码的主管部分中完成,因此即使原始代码因错误而取消,该部分也将始终正确完成。
第一个.bat
@echo off
if "%~1" equ "Original" goto Original
rem This supervisor section run the original code in a separate cmd.exe context
rem and restore the files if an error happened in the original code
(
cmd /C "%~F0" Original
if not exist second.bat (
echo Error detected! Restoring files
ren first.bat second.bat & ren temporary.bat first.bat
)
goto :EOF
)
:Original
( ren first.bat temporary.bat & ren second.bat first.bat
call :label1
echo Returned from :label1
call :label2
echo Returned from :label2
ren first.bat second.bat & ren temporary.bat first.bat )
echo This is first.bat ending...
二.bat
@echo off
:label1
echo I am label1 subroutine at second.bat
exit /B
:label2
set "var="
if %var% equ X echo This line cause a run-time error!
exit /B
输出
I am label1 subroutine at second.bat
Returned from :label1
No se esperaba X en este momento.
Error detected! Restoring files