2

I need to have my 2.bat script behaviour depending on the name of calling script.

Scenario: 2.bat is invoked from many other external scripts, which I am not entitled to change. Only 2.bat is under my thumb.

1.bat:

...
call 2.bat

2.bat:

...here place something extracting "1.bat"...
aschipfl
  • 33,626
  • 12
  • 54
  • 99
jikou
  • 39
  • 2
  • 7
    Possible duplicate of [Batch (.bat): get the name of the first script, not the current one](http://stackoverflow.com/questions/10087812/batch-bat-get-the-name-of-the-first-script-not-the-current-one) – geisterfurz007 Mar 29 '17 at 10:19

3 Answers3

4

As you cant change the calling bat there will be almost impossible to get its name if it is triggered through the cmd console (may be a memory dump could help?) as then the ProcessId will hold information only for the cmd.exe. The command prompt history could give you some information but it would be unreliable (and requires a dump to a temporary file)

If the calling bat is double clicked you can use this:

 setlocal enableDelayedExpansion
for /f "tokens=2* delims= " %%a in ("%cmdcmdline%") do (
    if /i "%%~a" equ "/c" (
        for %%# in (%%~b) do (
            echo calling bat : %%~#
        )
    ) else (
        doskey /history >"%tmp%\cmd.history"
        for /f "usebackq tokens=* delims=" %%# in ("%tmp%\cmd.history") do (
            set "last_command=%%#"
        )
        echo probably this is the calling bat: !last_command!
        del /q /f "%tmp%\cmd.history"
    )
) 


pause
npocmaka
  • 55,367
  • 18
  • 148
  • 187
2

You can get the name of a calling batch with a trick.

Assuming you have a first.bat(you can't controll) it could look like this

@echo off
set caller=empty
echo This is %~0

for /L %%n in (1 1 3) do (
    echo(
    echo #1 before calling, n=%%n
    call second %%n
)

echo Back to %~0

And your second.bat detects the caller

@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" %*"
    )
    echo BACK
    endlocal
)
echo NEVER REACHED
exit /b

:mainFunc
echo :mainFunc of %~nx0 arg1=%1 is called from '%caller%'/%callType%
exit /b
jeb
  • 78,592
  • 17
  • 171
  • 225
0

I've adjusted jikou's and jeb's code a little bit so it can also detect the caller function from the caller script.

detectCallerScript.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 *** 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" %%0 %*
    ) else (
        set "callType=cmd-line"
        cmd /c "call "%~d0\:mainFunc\..%~pnx0" %%0 %*"
    )
    endlocal
)
echo(NEVER REACHED
exit /b

:mainFunc
set "source=%~1"
shift /1
:mainFuncLoop
set args=%args%%1 
if "%~2" neq "" shift /1&goto:mainFuncLoop
if defined args set "args=%args:~0,-1%"
echo(:mainFunc of %~nx0 source=%source% with args="%args%" is called from '%caller%'/%callType%
exit /b

scriptCaller.bat:

@echo off
set caller=empty
echo(%~0: call detectCallerScript hi there
call detectCallerScript hi there
echo(Back to %~0
echo(
call:someFunc
exit /b

:someFunc
set caller=empty
echo(%~n0 %~0: call detectCallerScript hi there
call detectCallerScript hi there
echo(Back to %~0
echo(

Output:

scriptCaller.bat: call detectCallerScript hi there
:mainFunc of detectCallerScript.bat source=scriptCaller.bat with args="hi there" is called from '{path}\scriptCaller.bat'/batch
Back to scriptCaller.bat

scriptCaller :someFunc: call detectCallerScript hi there
:mainFunc of detectCallerScript.bat source=:someFunc with args="hi there" is called from '{path}\scriptCaller.bat'/batch
Back to :someFunc
Dharman
  • 30,962
  • 25
  • 85
  • 135