我正在编写一个包含其他文件生成的复杂批量补丁文件。我知道批次不是最好的,但我大部分时间都在使用它。但是,如果我不想为每个子例程创建单独的文件,那么很难将所有子例程保留在所有文件中。我的问题是,是否有任何方法可以保存多个子程序的库文件并以某种方式调用它们?
答案 0 :(得分:1)
所以我要回答我自己的问题,因为我设法让事情有效。
假设您有main.bat和lib.bat文件。
Main.bat
@ECHO off
SETLOCAL
SET return=
SET reference=this is just a reference variable
CALL lib.bat return "subroutine" "static arg" reference
IF NOT "%ERRORLEVEL%"=="0" (
ECHO Execution failed - %ERRORLEVEL%
EXIT /b 1
)
ECHO.
ECHO subroutine return value: "%return%"
ECHO.
CALL lib.bat NUL "procedure" "static arg" reference
ECHO.
CALL lib.bat return "error" "static arg" reference
IF NOT "%ERRORLEVEL%"=="0" (
ECHO Execution failed - %ERRORLEVEL%
EXIT /b 1
)
ENDLOCAL
EXIT /b 0
Lib.bat
@ECHO off
::
:: ===================================================================================
:: Library Main Handler
:: ===================================================================================
:: %~1 - [out] - NUL | reference to a return variable
:: %~2 - [in] - subroutine label to be invoked
:: %~3+ - [in] - optional arguments to the subroutine
::
:: ERRORLEVEL is passed through to the caller
::
SETLOCAL ENABLEDELAYEDEXPANSION ENABLEEXTENSIONS
SET callSub=%~2
SET return=
SET args=
IF "%callSub%"=="" (
ECHO Subroutine label was not provided to the library. 1>&2
EXIT /b 1
)
:buildUpArgumentList
IF "%~3"=="" GOTO end_buildUpArgumentList
SET args=%args% "%~3"
SHIFT /3
GOTO buildUpArgumentList
:end_buildUpArgumentList
IF NOT "%~1"=="NUL" (
call:%callSub% return %args%
IF NOT "!ERRORLEVEL!"=="0" (
EXIT /b !ERRORLEVEL!
)
) ELSE (
call:%callSub% %args%
IF NOT "!ERRORLEVEL!"=="0" (
EXIT /b !ERRORLEVEL!
)
)
(
ENDLOCAL
IF NOT "%~1"=="NUL" (
SET %~1=%return%
)
)
EXIT /b 0
::
:: ===================================================================================
:: Library Subroutine Definitions
:: ===================================================================================
::
:subroutine <r_return> <static> <r_reference>
SETLOCAL
ECHO subroutine^<static^>: "%~2"
ECHO subroutine^<r_reference^>: "!%~3!"
(
ENDLOCAL
SET %~1=subroutine executed OK
)
EXIT /b 0
:procedure <static> <r_reference>
SETLOCAL
ECHO procedure^<static^>: "%~1"
ECHO procedure^<r_reference^>: "!%~2!"
ENDLOCAL
EXIT /b 0
:error <r_return> <static> <r_reference>
SETLOCAL
ECHO error^<static^>: "%~2"
EXIT /b 2
ECHO error^<r_reference^>: "!%~3!"
(
ENDLOCAL
SET %~1=error executed OK
)
EXIT /b 0
输出:
subroutine<static>: "static arg"
subroutine<r_reference>: "this is just a reference variable"
subroutine return value: "subroutine executed OK"
procedure<static>: "static arg"
procedure<r_reference>: "this is just a reference variable"
error<static>: "static arg"
Execution failed - 2
一些意见:
其他想法:
非常感谢任何其他评论!
答案 1 :(得分:1)
更简单的方法是使用以下技巧:
例如:
(
rem Switch the active context to the library file:
ren "%~0" main.bat
ren libraryFile.bat "%~0"
rem From this line on you may call any function in the library file, for example:
call :FUNCTION
rem Switch the context back to original file
ren "%~0" libraryFile.bat
ren main.bat "%~0"
)
有关详细信息,请参阅: How to package all my functions in a batch file as a seperate file?