mẻ này phát hiện tên của kịch bản gọi hoặc thậm chí nếu nó được gọi là trực tiếp từ dòng lệnh
@echo off
setlocal DisableDelayedExpansion
set "func=%~0"
for /F "delims=\" %%X in ("%func:*\=%") do set "func=%%X"
if ":" == "%func:~0,1%" (
goto %func%
)
REM *** Get the name of the caller
(
(goto) 2>nul
setlocal DisableDelayedExpansion
call set "caller=%%~f0"
call set _caller=%%caller:*%%~f0=%%
if defined _caller (
set "callType=batch"
call "%~d0\:mainFunc\..%~pnx0" %*
) ELSE (
set "callType=cmd-line"
cmd /c "call "%~d0\:mainFunc\..%~pnx0" %*"
)
endlocal
)
echo NEVER REACHED
exit /b
:mainFunc
echo :mainFunc of %~nx0 arg1=%1 is called from '%caller%'/%callType%
exit /b
Nó sử dụng thực tế, rằng một tuyên bố (goto)
sẽ loại bỏ một cấp so với chồng.
Kết quả này để lại tệp lô hiện tại và %~f0
sẽ là tên của tập lệnh người gọi (và %~0
chức năng hiện tại của lô đó) hoặc văn bản %~f0
trong trường hợp được gọi từ dòng lệnh.
Sau đó, kịch bản riêng được gọi là một lần nữa với "%~d0\:mainFunc\..%~pnx0"
ngoài Script
Để sử dụng dễ dàng, bạn có thể thêm một tập tin helper hàng loạt.
Sử dụng nó trong các kịch bản của riêng bạn với dòng này
@echo off
<:GetCaller <nul call GetCaller.bat myCallerVar
echo This batch was called from "%myCallerVar%"
Tên tập tin batch helper GetCaller.bat
@echo off
setlocal DisableDelayedExpansion
set "func=%~0"
for /F "delims=\" %%X in ("%func:*\=%") do set "func=%%X"
if ":" == "%func:~0,1%" (
goto %func%
)
REM *** STEP1
REM *** Get the filename of the caller of this script, needed for later restart that
(
(goto) 2>nul
setlocal DisableDelayedExpansion %= it could be reenabled by the GOTO =%
set "_returnVar=%~1"
call set "_lastCaller=%%~f0"
call set "_argToLastCaller=%%*"
call "%~d0\:Step2\..%~pnx0" %*
)
exit /b %= This is never reached =%
:Step2
REM *** STEP2
REM *** Get the filename/cmd-line of the caller of the script
(
(goto) 2>nul
(goto) 2>nul
setlocal DisableDelayedExpansion %= it could be reenabled by the GOTO =%
set "_returnVar=%_returnVar%"
set "_lastCaller=%_lastCaller%"
set "_argToLastCaller=%_argToLastCaller%"
call set "caller=%%~f0"
call set _caller=%%caller:*%%~f0=%%
if defined _caller (
set "callType=batch"
call "%~d0\:Step3batch\..%~pnx0"
) ELSE (
set "callType=cmd-line"
cmd /c "call "%~d0\:Step3batch\..%~pnx0" "
)
endlocal
)
exit /b %= This is never reached =%
:Step3batch
REM *** STEP3 Restart the requester batch, but jump to the label :GetCaller
call :GetCaller
exit /b %= This is never reached =%
:GetCaller
REM *** This uses the trick, that starting a batch without CALL will jump to the last used label
if "%_returnVar%" NEQ "" set "%_returnVar%=%_caller%"
%_lastCaller% %_argToLastCaller%
echo #6 never reached
Tôi không sử dụng lập luận, Bali C đã làm. – KurzedMetal
xin lỗi, đã đọc câu trả lời của bạn! – CharlesB