Discussion forum for all Windows batch related topics.
Moderator: DosItHelp
-
carlos
- Expert
- Posts: 503
- Joined: 20 Aug 2010 13:57
- Location: Chile
-
Contact:
#1
Post
by carlos » 01 Apr 2015 14:24
Hello. Time ago a method for get a
password input, showing the * was developed using xcopy.exe. But today, I write a new method, using replace.exe.
The code is very readable, support almost all characters, including the !
Example:
C:\dev>password_input.cmd
Enter a Password:******
Your input was:carlos
password_input.cmd
Code: Select all
@Echo Off
SetLocal EnableExtensions EnableDelayedExpansion
Set /P "=Enter a Password:" < Nul
Call :PasswordInput
Echo(Your password text:!pwd!
Pause
Goto :Eof
:PasswordInput
:: consolesoft.com/batch/?#password_input
::Author: Carlos Montiers Aguilera
::Last updated: 20150405. Created: 20150401.
::Set variable pwd with input password
::Needs delayed expansion enabled
Set "pwd="
Set "INTRO=" &For /F "skip=1" %%# in (
'"Echo(|Replace.exe ? . /U /W"'
) Do If Not Defined INTRO Set "INTRO=%%#"
For /F %%# In (
'"Prompt $H &For %%_ In (_) Do Rem"') Do Set "BKSPACE=%%#"
:_PasswordInput_Kbd
Set "Excl="
Set "CHR=" &For /F skip^=1^ delims^=^ eol^= %%# in (
'Replace.exe ? . /U /W') Do If Not Defined CHR (
Set "CHR=%%#" &If "%%#"=="!" Set "Excl=yes")
If "!INTRO!"=="!CHR!" Echo(&Goto :Eof
If "!BKSPACE!"=="!CHR!" (If Defined pwd (
Set "pwd=!pwd:~0,-1!"
Set /P "=!BKSPACE! !BKSPACE!" <Nul)
Goto :_PasswordInput_Kbd
) Else If Not Defined Excl (
Set "pwd=!pwd!!CHR:~0,1!"
) Else Set "pwd=!pwd!^!"
Set /P "=*" <Nul
Goto :_PasswordInput_Kbd
Last edited by
carlos on 04 Apr 2015 21:18, edited 11 times in total.
-
npocmaka_
- Posts: 516
- Joined: 24 Jun 2013 17:10
- Location: Bulgaria
-
Contact:
#2
Post
by npocmaka_ » 01 Apr 2015 15:28
I have an endless "
*Path not found - CONIN$"
-
carlos
- Expert
- Posts: 503
- Joined: 20 Aug 2010 13:57
- Location: Chile
-
Contact:
#3
Post
by carlos » 01 Apr 2015 15:36
npocmaka, thanks for report it. I'm updated for not use it. Please test again.
-
npocmaka_
- Posts: 516
- Joined: 24 Jun 2013 17:10
- Location: Bulgaria
-
Contact:
#4
Post
by npocmaka_ » 01 Apr 2015 15:42
Great!
Now its working and I cant broke it with special characters
-
carlos
- Expert
- Posts: 503
- Joined: 20 Aug 2010 13:57
- Location: Chile
-
Contact:
#5
Post
by carlos » 04 Apr 2015 14:00
Thanks, I've updated the code improving the readability and also fixing a problem if you press Ctrl+Z.
-
aGerman
- Expert
- Posts: 4678
- Joined: 22 Jan 2010 18:01
- Location: Germany
#6
Post
by aGerman » 04 Apr 2015 14:31
Carlos
your script works great except if there are parentheses or ampersands in the batch file name.
Those will break your first replace.exe call. Rather escape the pipe character instead of enclosing the command line into quotation marks.
Code: Select all
'Echo(^|Replace.exe "%~f0" . /U /W') Do Set "INTRO=%%#"
Regards
aGerman
-
carlos
- Expert
- Posts: 503
- Joined: 20 Aug 2010 13:57
- Location: Chile
-
Contact:
#7
Post
by carlos » 04 Apr 2015 15:27
Thanks aGerman for the info.
For avoid problems with filenames with special characters I replace %~f0 with a wildcard. It works.
Seems that replace.exe accept wildcards for found a file (undocumented?).
Also, previously I use the full path of the script file (%~f0), replacing in the current directory (.). Because it if the current directory inside the script would different that the path of the script it will copy the current script if a file with the same name and old date exist in the current directory.
Now, I specify a file of the current directory using the wildcard ?, because it, both are in the current directory, have the same date, never a replace operation would happen.
Script updated !!!
-
aGerman
- Expert
- Posts: 4678
- Joined: 22 Jan 2010 18:01
- Location: Germany
#8
Post
by aGerman » 04 Apr 2015 15:38
Because it if the current directory inside the script would different that the path of the script it will copy the current script if a file with the same name and old date exist in the current directory.
I already tried to change the working directory but that didn't ever happen. You could have fixed that by using "%~dp0." Nevermind. The wildcard workaround seems to work well.
Regards
aGerman
EDIT: Now I see your point. The script has to exist in both directories then ...
-
carlos
- Expert
- Posts: 503
- Joined: 20 Aug 2010 13:57
- Location: Chile
-
Contact:
#9
Post
by carlos » 04 Apr 2015 16:00
aGerman, also I tested and updated again for work on windows xp.
On windows xp replace.exe, unlike windows 8, if none replace happen it print at end a text saying it.
windows xp spanish pressing a:
Code: Select all
C:\DEV>replace.exe ? . /U /W
Presione cualquier tecla para continuar . . .
a
No se ha reemplazado ningún archivo
Script updated again for works on windows xp.Edit:Updated again fixing a problem with the ! on windows xp
-
aGerman
- Expert
- Posts: 4678
- Joined: 22 Jan 2010 18:01
- Location: Germany
#10
Post
by aGerman » 04 Apr 2015 17:24
Carlos
May you run that version against XP please:
Code: Select all
@echo off &setlocal
<nul set /p "=Enter your password: "
call :HInput pw
echo Input length is %errorlevel%
setlocal EnableDelayedExpansion
echo Your password is !pw!
pause
goto :eof
:HInput [ByRef_VarName]
:: inspired by Carlos
if "%__HI__%" neq "__HI__" (
setlocal DisableDelayedExpansion EnableExtensions
set "CR=" &set "S=" &set "N=0" &set "__HI__=__HI__"
for /f "skip=1" %%i in ('echo(^|replace ? . /u /w') do if not defined CR set "CR=%%i"
for /f %%i in ('"prompt $H &for %%b in (1) do rem"') do set "BS=%%i"
)
set "C="
for /f skip^=1^ delims^=^ eol^= %%i in ('replace ? . /u /w') do if not defined C set "C=%%i"
setlocal EnableDelayedExpansion EnableExtensions
if "!CR!"=="!C!" (
echo(
if "%~1"=="" (
echo(!S!
endlocal &endlocal &exit /b %N%
) else (
if defined S (
for /f delims^=^ eol^= %%i in ("!S!") do endlocal &endlocal &set "%~1=%%i" &exit /b %N%
) else endlocal &endlocal &set "%~1=" &exit /b 0
)
)
if "!BS!"=="!C!" (
set "C="
if defined S set /a "N -= 1" &set "S=!S:~,-1!" &<nul set /p "=%BS% %BS%"
) else set /a "N += 1" &<nul set /p "=*"
if not defined S (
endlocal &set "N=%N%" &set "S=%C%"
) else for /f delims^=^ eol^= %%i in ("!S!") do endlocal &set "N=%N%" &set "S=%%i%C%"
goto HInput
Regards
aGerman
EDIT slighty changed ...
Carlos' further improvements implemented.
Explanation of used symbols:
:HInput is for "hidden
input"
CR carriage return character
BS backspace character
C entered character
S string of entered characters
N number of entered characters in S
__HI__ helper variable (instead of having a helper label) to skip the initialization of variables
-
carlos
- Expert
- Posts: 503
- Joined: 20 Aug 2010 13:57
- Location: Chile
-
Contact:
#11
Post
by carlos » 04 Apr 2015 17:55
aGerman, your code works ok on xp.
I only will add to it the enableextensions because exit /b works with it.
Also, in my last update, I only used "skip=1" for set the CR variable.
-
aGerman
- Expert
- Posts: 4678
- Joined: 22 Jan 2010 18:01
- Location: Germany
#12
Post
by aGerman » 04 Apr 2015 18:12
Thanks Carlos, did the changes.
By the way feel free to adopt my version in whatever kind. It's basically nothing but your idea. I just added the character counting and tried to make it a little more readable by line indentations.
Regards
aGerman
-
carlos
- Expert
- Posts: 503
- Joined: 20 Aug 2010 13:57
- Location: Chile
-
Contact:
#13
Post
by carlos » 04 Apr 2015 21:21
thanks aGerman, I only renamed the variable line to pwd, is short like pw in your script.
-
aGerman
- Expert
- Posts: 4678
- Joined: 22 Jan 2010 18:01
- Location: Germany
#14
Post
by aGerman » 05 Apr 2015 08:29
Well perhaps my variable names are too short to be self-explanatory.
For those who are interested in I appended the explantion.
Regards
aGerman
-
Squashman
- Expert
- Posts: 4486
- Joined: 23 Dec 2011 13:59
#15
Post
by Squashman » 22 Oct 2015 10:42
carlos wrote:Hello. Time ago a method for get a password input, showing the * was developed using xcopy.exe.
I can't find that thread. I thought I remember commenting in that thread but can't find it.