2015-05-11 117 views
3

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 

從文件1我想在一個子例程的調用批處理批處理文件2。
我試過例如call file2.bat:Demo但它沒有給出正確的結果。

我該如何做到這一點?

回答

3

與子程序的文件必須看起來像:

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

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

然後從其他的文件,你可以這樣調用它

call file2.bat demo "arg-one" 
+0

您是否閱讀過MCND的答案?我認爲你喜歡這種技巧或者你已經知道了? – jeb

+0

@jeb - 好戲! – npocmaka

+0

這對我來說看起來更清潔 –

4

你可以寫你的函數文件(本示例中是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 

然後調用者批處理可以是類似於

@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 

在這種情況下,標籤需要在兩個文件中使用相同的名稱來定義。

「庫」批處理文件的直接調用將替換call :label的上下文,並且在調用批處理時,內部執行goto :label,並且代碼在指示的標籤內繼續。當被調用的批處理文件結束時,上下文被釋放並且call :label之後的代碼繼續。

編輯

如傑布指出在註釋中,有在該方法中的缺點。在被調用的批處理文件中運行的代碼不能使用%0來檢索被調用函數的名稱,它將返回批處理文件的名稱。但是,如果需要,調用者可以按照示例代碼中所示的方式執行此操作。

編輯2016年12月27日

回答到dbenham,我也沒有辦法知道,如果它是一個編碼錯誤或預期的功能,但是這是如何處理工作

的線條批處理文件在批處理「上下文」創建時在內部BatLoop函數內處理。該函數接收作爲其參數之一的指向導致創建「上下文」的命令的指針。

在此函數中,批處理文件中的命令被迭代。循環遍歷命令的循環在每次迭代中進行測試:如果啓用了擴展,它是批處理文件中的第一行,並且啓動上下文的命令的參數以冒號(標號)開頭,goto生成跳轉到標籤。

到此爲止,我必須假設這是處理call :label語法的預期行爲:創建一個新的「上下文」,加載文件,跳轉到標籤。

但是接收到的命令參數從不改變,另一個變量用於跟蹤批處理文件中命令的執行情況。如果新的批處理文件被加載到/覆蓋當前批處理「上下文」(我們還沒有使用call命令),加載新的批處理代碼後,BatLoop會重置行計數(我們從加載文件的第一行開始)和,voila,循環開始處的條件(擴展啓用,第一行,冒號)再次爲真(指向的輸入命令未更改),並生成新的goto

+1

我喜歡這個技巧,只有一個_drawback_,在輔助批處理的被調用函數中'%0'不包含函數名,它包含批處理文件名,但幾乎沒有人使用'%0'來檢索當前功能名稱這是一個非常小的差異 – jeb

+0

驚人的! :-) .... – npocmaka

+0

@jeb,當然你是對的。考慮到有人可能需要函數名稱,發佈的示例代碼包含一個'echo',在將其餘工作委託給「庫」之前,檢索函數名稱。現在它被包含在答案中,謝謝。 –

相關問題