Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Call a subroutine in a batch from another batch file

Tags:

batch-file

file1.bat:

@echo off
 :Test
echo in file one
call file2.bat (Here i want to call only Demo routine in the file2.bat)

file2.bat:

:hello
echo in hello
:Demo
 echo in Demo

From the batch file1 I want to make a call to a sub routine in the batch file2.
I tried for example call file2.bat:Demo but it didn't give the correct result.

How I can achieve this?

like image 365
user1844634 Avatar asked May 11 '15 12:05

user1844634


2 Answers

the file with subroutines must look like:

@echo off
call :%*
exit /b %errorlevel%

:hello
echo in hello
exit /b 0
:Demo
 echo in Demo with argument %1
 exit /b 0

then from the other file you can call it like

call file2.bat demo "arg-one"
like image 75
npocmaka Avatar answered Oct 23 '22 16:10

npocmaka


You can write your functions file (in this sample it is library.cmd) as

@echo off
    setlocal enableextensions
    rem Not to be directly called
    exit /b 9009

:test
    echo test [%*]
    goto :eof

:test2
    echo test2 [%*]
    goto :eof

:testErrorlevel
    echo testErrorlevel
    exit /b 1

And then the caller batch can be something like

@echo off
    setlocal enableextensions disabledelayedexpansion

    call :test arg1 arg2 arg3
    call :test2 arg4 arg5 arg6
    call :testErrorlevel && echo no errorlevel || echo errorlevel raised

    goto :eof

:test
:test2
    echo calling function %0
    library.cmd %*

:testErrorlevel
    echo calling function %0
    library.cmd 

In this case, the labels need to be defined with the same name in both files.

The direct invocation of the "library" batch file will replace the context of the call :label, and when the invoked batch is readed, a goto :label is internally executed and code continues inside the indicated label. When the called batch file ends, the context is released and the code after the call :label continues.

edited

As Jeb points in comments, there is a drawback in this method. The code running in the called batch file can not use %0 to retrieve the name of the function being called, it will return the name of the batch file. But if needed, the caller can do it as shown in the sample code.

edited 2016/12/27

Answering to dbenham, I have no way to know if it was a coding error or an intended feature, but this is how the process works

The lines in batch file are processed inside the inner BatLoop function when a batch "context" is created. This function receives, as one of its arguments, a pointer to the command that caused the "context" to be created.

Inside this function the commands in the batch file are iterated. The loop that iterates over the commands makes a test in each iteration: if extensions are enabled, it is the first line in the batch file and the arguments of the command that started the context starts with a colon (a label), a goto is generated to jump to the label.

Up to here, I have to suppose that this is the intended behaviour to handle the call :label syntax: create a new "context", load the file, jump to the label.

But the command argument received is never changed, a different variable is used to track the execution of the commands in the batch file. If a new batch file is loaded into / overwrites the current batch "context" (we have not used call command), after loading the new batch code, BatLoop resets the line count (we start at the first line of the loaded file) and, voila, the condition at the start of the loop (extensions enabled, first line, the colon) is true again (the pointed input command has not been changed) and a new goto is generated.

like image 7
MC ND Avatar answered Oct 23 '22 16:10

MC ND