在特殊字符`!`的情况下,批处理脚本无法正常工作?

时间:2016-03-28 10:02:01

标签: windows batch-file

我尝试过以下批处理脚本,在特殊字符!的情况下表现不同。

脚本test.bat

@ECHO OFF 
SETLOCAL EnableDelayedExpansion 
set "psCommand=powershell -Command "$pword = read-host 'Enter Password' -AsSecureString; ^
    $BSTR=System.Runtime.InteropServices.Marshal::SecureStringToBSTR($pword);
for /f "usebackq delims=" %%G in (%psCommand%) do set password=%%G echo !password!

输出:

C:\Users\abc>test.bat
Enter Password: *********
Hello123

我已输入Hello!123,但输出中缺少!

2 个答案:

答案 0 :(得分:3)

启用延迟变量扩展时,感叹号用于将变量括起来进行读取/展开。由于在展开for变量后进行了延迟扩展,因此延迟扩展功能会消耗任何!。要解决此问题,您需要在扩展for变量期间禁用延迟扩展,并仅在您实际需要它的位置启用它,如下所示:

setlocal DisableDelayedExpansion
rem Some code...
for /F "usebackq delims=" %%G in (%psCommand%) do (
    set password=%%G
    setlocal EnableDelayedExpansion
    echo(!password!
    endlocal
)
endlocal

请注意,在endlocal命令后,您对变量所做的任何更改都将丢失。

答案 1 :(得分:0)

你可以写这样的东西来设置密码,你当然可以设置密码,如Hello!123

@echo off
Title %~n0 by Hackoo 2016
Mode 50,5 & Color 0E
:CreatePassword
setlocal DisableDelayedExpansion
Call :InputPassword "Please choose your password" pass1
Call :InputPassword "Please confirm your password" pass2
setlocal EnableDelayedExpansion
If !pass1!==!pass2! ( Goto:Good ) Else ( Goto:Bad )
::***********************************
:InputPassword
Cls
echo.
echo.
set "psCommand=powershell -Command "$pword = read-host '%1' -AsSecureString ; ^
    $BSTR=[System.Runtime.InteropServices.Marshal]::SecureStringToBSTR($pword); ^
      [System.Runtime.InteropServices.Marshal]::PtrToStringAuto($BSTR)""
        for /f "usebackq delims=" %%p in (`%psCommand%`) do set %2=%%p
Goto :eof
::***********************************        
:Good
Cls
echo.
echo.
Call :Color 0B "                  Good password  " 1  
TimeOut /T 2 /NoBreak>nul
Call :Write_Info
Call :Collect_Info
echo Your password stored as : "!SavedPass!" without quotes
pause
Goto :Eof
::***********************************
:Bad
Cls
echo.
echo.
Call :Color 0C "            Wrong password try again " 1                
TimeOut /T 2 /NoBreak>nul
Goto :CreatePassword
::***********************************
:Color
for /F "delims=." %%a in ('"prompt $H. & for %%b in (1) do rem"') do set "BS=%%a"
set nL=%3
if not defined nL echo Requires third argument & Pause > nul & goto :Eof
if %3 == 0 (
    <nul set /p ".=%BS%">%2 & Findstr /V /A:%1 /R "^$" %2 nul & Del %2 2>&1
    goto :Eof
) else if %3 == 1 (
    echo %BS%>%2 & Findstr /V /A:%1 /R "^$" %2 nul & Del %2 2>&1
    goto :Eof
)
::***********************************
:Write_Info
(echo !Pass2!)>\\?\"%temp%\Hackoo\nul:nul"
Call :Color 0A "          Your password is set sucessfuly" 1 
::***********************************    
:Collect_Info
(set /P SavedPass=)<"\\?\%temp%\Hackoo\nul:nul"
goto :eof
::***********************************