使用参数从包含的批处理文件中调用函数 [英] Calling function from included batch file with a parameter

查看:517
本文介绍了使用参数从包含的批处理文件中调用函数的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在我的主批处理文件中,我包括另一个批处理文件,并且要调用其中定义的函数,代码如下:

In my main batch file I include another batch file and want to call a function defined in there, code looks like following:

@echo off
call define_wait.bat

if "%1"=="WAIT" (
    call :WAIT_AND_PRINT 5
    echo.
)

REM rest...

我的 define_wait.bat 如下:

:WAIT_AND_PRINT
set /a time=%1
for /l %%x in (1, 1, %time%) do (
    ping -n 1 -w 1000 1.0.0.0 > null
    echo|set /p=.
)
goto :EOF

:WAIT
set /a time="%1 * 1000"
ping -n 1 -w %time% 1.0.0.0 > null
goto :EOF

问题是,如果我在另一个批处理文件中定义了wait函数,则该函数将不起作用,调用call :WAIT_AND_PRINT 5不能正确地传递参数(错误:缺少操作数)...如果我将代码从 define_wait.bat 复制到我的主批处理文件中,一切正常...

The problem is that if I define the wait function in another batch file it does not work, calling call :WAIT_AND_PRINT 5 does not hand on the parameter correctly (Error: missing operand)... If I copy my code from my define_wait.bat int my main batch file, everything works fine...

我如何正确地做到这一点?

How would I make that correctly?

推荐答案

直到

I wasn't aware of this until jeb commented it, but here's a quick demonstration of the call bug he mentioned, using some utility functions I had lying around.

functions.bat:

:length <"string">
rem // sets errorlevel to the string length (not including quotation marks)
setlocal disabledelayedexpansion
if "%~1"=="" (endlocal & exit /b 0) else set ret=1
set "tmpstr=%~1"
for %%I in (4096 2048 1024 512 256 128 64 32 16 8 4 2 1) do (
    setlocal enabledelayedexpansion
    if not "!tmpstr:~%%I,1!"=="" (
        for %%x in ("!tmpstr:~%%I!") do endlocal & (
            set /a ret += %%I
            set "tmpstr=%%~x"
        )
    ) else endlocal
)
endlocal & exit /b %ret%

:password <return_var>
rem // prompts user for password, masks input, and sets return_var to entered value
setlocal disabledelayedexpansion
<NUL set /P "=Password? "
set "psCommand=powershell -noprofile "$p=read-host -AsSecureString;^
$m=[Runtime.InteropServices.Marshal];$m::PtrToStringAuto($m::SecureStringToBSTR($p))""
for /f "usebackq delims=" %%p in (`%psCommand%`) do endlocal & set "%~1=%%p"
goto :EOF

main.bat:

@echo off & setlocal

rem // demo return value
call :password pass

setlocal enabledelayedexpansion
echo You entered !pass!

rem // demo bubbling up of %ERRORLEVEL%
call :length "!pass!"
echo Password length is %ERRORLEVEL%

endlocal
goto :EOF

rem // ====== FUNCTION DECLARATIONS =======

:length <"string">
:password <return_var>
functions.bat %*

输出:

密码? *********
您输入了一些内容
密码长度为9

Password? *********
You entered something
Password length is 9

此网页提供了说明:

如果不使用CALL执行第二个批处理文件 ,则可能会遇到一些错误的行为:如果两个批处理文件都包含一个具有相同名称的标签,并且您以前曾使用CALL跳转到该标签在第一个脚本中,您会发现第二个脚本的执行从相同的标签开始.即使第二个标签不存在,这仍然会引发错误找不到批次标签" .始终使用CALL可以避免此错误.

If you execute a second batch file without using CALL you may run into some buggy behaviour: if both batch files contain a label with the same name and you have previously used CALL to jump to that label in the first script, you will find execution of the second script starts at the same label. Even if the second label does not exist this will still raise an error "cannot find the batch label". This bug can be avoided by always using CALL.

如果您曾经用C ++进行过任何编码,那么将main.bat中的标签视为.h文件中的函数 declarations 会有所帮助,而functions.bat中的标签将与之对应在.cpp文件中使用 definitions 的功能.或在.NET中,可以说main.bat标签就像DllImport("functions.bat")一样.

If you've ever done any coding in C++, it helps to think of the labels in main.bat as function declarations in a .h file, while the labels in functions.bat would correspond to function definitions in a .cpp file. Or in .NET, the main.bat labels would be like DllImport("functions.bat") so to speak.

这篇关于使用参数从包含的批处理文件中调用函数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆