Package (.bat): get the name of the first script, not the current

I have first.bat and second.bat .

first.bat: call second.bat

Second: echo %~n0 (displays the name of the executable file)

The output is second.bat , but I want it to display the name of the calling file, not it.

Is it possible?

+6
source share
4 answers

You cannot do this without a complicated system call to get the identifier of the parent process or pass something as an argument or environment variable, as in the KurzedMetal and BaliC messages. Accepted system calls are described in detail in this post ; you will have to import the DLL calls into a batch, so this is not a small thing.

0
source

Store the value %~n0 in an environment variable before calling second.bat

+3
source

I think the easiest way to do this is to pass the file name of the first batch as a parameter to the second, like this.

 REM First.bat call Second.bat %~n0 REM Second.bat echo %1 

Hope this helps!

+3
source

This batch detects the caller name script or even if it is called directly from the command line

 @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 

It exploits the fact that the (goto) operator will remove one level from the stack.
This leads to the exit from the current batch file, and %~f0 will be the name of the calling script (and %~0 current function of this batch) or the text %~f0 if called from the command line.

Then the native script is called again with "%~d0\:mainFunc\..%~pnx0"

External script

For ease of use, you can add an auxiliary batch file.
Use it in your scripts with this line

 @echo off <:GetCaller <nul call GetCaller.bat myCallerVar echo This batch was called from "%myCallerVar%" 

Name the helper batch file 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 
+2
source

Source: https://habr.com/ru/post/912841/


All Articles