【问题标题】:Can I mask an input text in a bat file?我可以屏蔽 bat 文件中的输入文本吗?
【发布时间】:2010-10-14 11:28:09
【问题描述】:

我正在编写一个批处理文件来执行一些其他程序。在这种情况下,我需要提示输入密码。我有什么方法可以屏蔽输入文本吗?我不需要打印 ******* 字符而不是输入字符。 Linux 的密码提示行为(键入时不打印)就足够了。

@echo off
SET /P variable=Password : 
echo %variable%
Pause

这将读取输入,但我无法使用这种方法屏蔽文本。

【问题讨论】:

标签: batch-file cmd command-prompt


【解决方案1】:

我可能会这样做:

..
echo Before you enter your password, make sure no-one is looking!
set /P password=Password:  
cls
echo Thanks, got that.
.. 

所以你得到一个提示,然后屏幕在输入后清除。

请注意,如果从命令提示符执行批处理文件,输入的密码将存储在 CMD 历史记录中(感谢@Mark K Cowan)。

如果这还不够好,我会切换到 python,或者编写可执行文件而不是脚本。

我知道这些都不是完美的解决方案,但也许一个对你来说已经足够了:)

【讨论】:

  • 请注意,如果从命令提示符执行批处理文件,输入的密码将存储在 CMD 历史记录中。没有反对意见,因为您几乎说 cmd 是该工作的错误工具。
  • 如果控制台中的命令历史记录对您不重要,您可以在cls 之后立即运行doskey /reinstall 清除先前的命令缓冲区。
  • 如果您不想使用 doskey /reinstall 并清除命令历史记录,另一种选择是在单独的终端窗口中运行上述代码并立即退出。请注意,它仍然不会用星号替换您键入的字符串。如果您不想运行 powershell,则可以选择上述解决方案。 C:\>start "console" cmd /c ireadconsole.bat
  • 另一种选择是使用类似:SET /P pw=C:\^> ^ 转义 > 以便密码提示看起来像标准 cmd 控制台提示。
【解决方案2】:

直到 XP 和 Server 2003,您可以使用另一个包含的工具 (VBScript) - 以下两个脚本可以完成您想要的工作。

首先,getpwd.cmd

@echo off
<nul: set /p passwd=Password: 
for /f "delims=" %%i in ('cscript /nologo getpwd.vbs') do set passwd=%%i
echo.

那么,getpwd.vbs

Set oScriptPW = CreateObject("ScriptPW.Password")
strPassword = oScriptPW.GetPassword()
Wscript.StdOut.WriteLine strPassword

getpwd.vbs 只是使用密码对象从用户那里输入密码,然后将其打印到标准输出(下一段将解释为什么终端不会显示密码)。

getpwd.cmd 命令脚本有点棘手,但它的基本工作原理如下。

"&lt;nul: set /p passwd=Password: " 命令的效果是输出没有尾随换行符的提示 - 这是从 bash shell 模拟 "echo -n" 命令的一种偷偷摸摸的方式。它将passwd 设置为一个空字符串作为不相关的副作用并且不等待输入,因为它从nul: 设备获取输入。

"for /f "delims=" %%i in ('cscript /nologo getpwd.vbs') do set passwd=%%i" 语句是最棘手的部分。它运行没有微软“广告”的 VBScript,因此唯一的行输出是密码(来自 VBscript "Wscript.StdOut.WriteLine strPassword"

需要将分隔符设置为空才能捕获带有空格的整个输入行,否则您只会得到第一个单词。 "for ... do set ..." 位将 passwd 设置为 VBScript 输出的实际密码。

然后我们回显一个空行(以终止"Password: " 行),代码运行后密码将在passwd 环境变量中。


现在,如前所述,scriptpw.dll 仅适用于 XP/2003。为了解决这个问题,您可以简单地将 XP/2003 系统的Windows\System32 文件夹中的scriptpw.dll 文件复制到您自己系统上的Winnt\System32Windows\System32 文件夹中。复制 DLL 后,您需要通过运行来注册它:

regsvr32 scriptpw.dll

要在 Vista 及更高版本上成功注册 DLL,您需要管理员权限。我还没有检查过这种举动的合法性,所以洞穴讲师。


如果您不是过度热衷于尝试追踪和注册较旧的 DLL 文件(出于方便或法律原因),还有另一种方法。更高版本的 Windows(那些没有所需 DLL 的版本)应该有 Powershell 可供您使用。

事实上,您确实应该考虑升级您的脚本以充分使用它,因为它是一种比cmd.exe 更强大的脚本语言。但是,如果您想将大部分代码保留为 cmd.exe 脚本(例如,如果您有 很多 段不想转换的代码),您可以使用相同的技巧.

首先,修改 cmd 脚本,使其调用 Powershell 而不是 CScript:

@echo off
for /f "delims=" %%i in ('powershell -file getpwd.ps1') do set passwd=%%i

Powershell 脚本同样简单:

$password = Read-Host "Enter password" -AsSecureString
$password = [Runtime.InteropServices.Marshal]::SecureStringToBSTR($password)
$password = [Runtime.InteropServices.Marshal]::PtrToStringAuto($password)
echo $password

虽然有一些编组来获取实际的密码文本。

请记住,要在您的计算机上运行本地未签名的 Powershell 脚本,您可能需要从(严厉,但非常安全)默认值修改执行策略,例如:

set-executionpolicy remotesigned

来自 Powershell 本身。

【讨论】:

  • 哇,那个
  • 有趣,它应该可以从 XP 中获得。我怀疑 Win7 还没有完成,如果它在那里不起作用(或者你必须做一些其他的诡计才能让它工作)。一些研究表明了原因:请参阅我的更新。
  • 不错。还需要注意的是,您可以将 VBS 文件替换为可以从命令行调用的任何等效语言。例如,您可以将 cscript 部分替换为:'python -c "from getpass import getpass; pwd = getpass(); print pwd;"'
  • 当这个问题是新问题时,我曾经使用过这种方式 - 我回答了 below 一种无需额外脚本的方式。
  • @Bill:因此我的部分开始于“现在,不幸的是,......” :-) 但是,我为答案添加了更多选项,希望能做得更好。具体来说,使用powershell而不是scriptpw.dll
【解决方案3】:

另一种选择是我的 EditV32 (x86) 或 EditV64 (x64) 命令行工具。例如:

editv32 -m -p "Password: " PWD

-m 表示“屏蔽输入”,-p 是提示符。用户的输入存储在 PWD 环境变量中。你可以在这里得到它:

https://westmesatech.com/?page_id=19

【讨论】:

  • 这不是唯一的闭源解决方案(Windows 是闭源的!)。当然,你可以不使用它......
  • 如果缺少源代码困扰您,请参阅我关于 ReadLine.exe 的其他答案。
  • 好一个!许可证允许您使用它。此外,易于集成。只是为了处理退出代码 1. 命令行出错,2 输入行为空白,3 环境变量未更改,4 使用 Ctrl-C 中止程序
  • 注意:editenv32/editenv64 和 readline 实用程序已被开源 editenv 实用程序取代。
【解决方案4】:

我阅读了网上所有关于如何在批处理文件中屏蔽密码的笨拙解决方案,使用 hide.com 解决方案的解决方案,甚至是使文本和背景颜色相同的解决方案。 hide.com 解决方案运行良好,但不是很安全,并且在 64 位 Windows 中无法运行。所以无论如何,使用 100% 微软实用程序,有办法!

首先,让我解释一下我的用途。我有大约 20 个自动登录到 Windows 的工作站。他们的桌面上有一个快捷方式——一个临床应用程序。机器被锁定,无法右键单击,只能访问桌面上的一个快捷方式。有时技术人员需要启动一些调试应用程序、浏览 Windows 资源管理器并查看日志文件,而无需关闭自动登录用户帐户。

这就是我所做的。

随心所欲,但我将我的两个批处理文件放在锁定的计算机可以访问的网络共享上。

我的解决方案利用了 Windows 的 1 个主要组件 - runas。 在客户端上为您将要创建的 runas.bat 放置一个快捷方式。 仅供参考,在我的客户端上,我重命名了快捷方式以便更好地查看并更改了图标。

您需要创建两个批处理文件。

我将批处理文件命名为 runas.batDebug Support.bat

runas.bat 包含以下代码:

cls
@echo off
TITLE CHECK CREDENTIALS 
goto menu

:menu
cls
echo.
echo           ....................................
echo            ~Written by Cajun Wonder 4/1/2010~
echo           ....................................
echo.
@set /p un=What is your domain username? 
if "%un%"=="PUT-YOUR-DOMAIN-USERNAME-HERE" goto debugsupport
if not "%un%"=="PUT-YOUR-DOMAIN-USERNAME-HERE" goto noaccess
echo.
:debugsupport
"%SYSTEMROOT%\system32\runas" /netonly /user:PUT-YOUR-DOMAIN-NAME-HERE\%un% "\\PUT-YOUR-NETWORK-SHARE-PATH-HERE\Debug Support.bat"
@echo ACCESS GRANTED! LAUNCHING THE DEBUG UTILITIES....
@ping -n 4 127.0.0.1 > NUL
goto quit
:noaccess
cls
@echo.
@echo.
@echo.
@echo.
@echo   \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
@echo   \\                                   \\
@echo   \\    Insufficient privileges         \\  
@echo   \\                                    \\
@echo   \\      Call Cajun Wonder             \\
@echo   \\                                    \\
@echo   \\              At                    \\
@echo   \\                                    \\
@echo   \\        555-555-5555                \\
@echo   \\                                    \\
@echo   \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
@ping -n 4 127.0.0.1 > NUL
goto quit
@pause
:quit
@exit

您可以为要授予访问权限的所有用户添加尽可能多的 if "%un%" 和 if not "%un%"。 @ping 是我制作秒计时器的笨拙方式。

这样就处理了第一个批处理文件 - 很简单吧?

这是Debug Support.bat的代码:

cls
@echo off
TITLE SUPPORT UTILITIES
goto menu

:menu
cls
@echo %username%
echo.
echo           .....................................
echo            ~Written by Cajun Wonder 4/1/2010~
echo           .....................................
echo.
echo What do you want to do? 
echo.
echo [1]  Launch notepad
echo.

:choice
set /P C=[Option]? 
if "%C%"=="1" goto notepad
goto choice

:notepad
echo.
@echo starting notepad....
@ping -n 3 127.0.0.1 > NUL
start notepad
cls
goto menu

我不是编码员,实际上大约一年前才开始涉足批处理脚本,而我发现的这种在批处理文件中屏蔽密码的方法非常棒!

我希望听到我以外的其他人能够从中得到一些用处!

【讨论】:

    【解决方案5】:

    我使用了 Blorgbeard 的上述解决方案,我认为这实际上很棒。然后我对其进行了如下增强:

    1. Google for ansicon
    2. 下载 zip 文件和示例文本文件。
    3. 安装(即复制2个文件到system32)

    像这样使用它:

    @echo off
    ansicon -p
    set /p pwd=Password:ESC[0;37;47m
    echo ESC[0m
    

    这会将控制台切换为灰色以供您输入密码,并在您完成后切换回来。 ESC 实际上应该是一个不可打印的字符,您可以将其从下载的示例文本文件(在记事本中显示为左箭头)复制到批处理文件中。您可以使用示例文本文件查找所有颜色组合的代码。

    如果您不是机器的管理员,您可能能够将文件安装在非系统目录中,那么您必须在调用程序并使用转义序列之前将该目录附加到脚本中的 PATH .如果您需要一个仅包含几个文件的非管理员可分发包,这甚至可能是当前目录。

    【讨论】:

    • 我无法对此进行测试,但希望输入的密码之后会出现在 cmd 历史记录中。
    • @MarkKCowan 这正是发生的事情。
    【解决方案6】:

    制作一个调用不可见字符所需的批处理文件,然后为正在调用的批处理文件创建一个快捷方式。

    右键

    属性

    颜色

    文字==黑色

    背景 == 黑色

    申请

    好的

    希望对你有帮助!!!!!!!!!

    【讨论】:

    【解决方案7】:

    这可能是一个较老的话题,但如果您使用的是 Windows Vista 或 7,我有一个非常有效的解决方案。我在这里制作了一个视频:http://www.youtube.com/watch?v=mk8uAa6PIFM

    批处理文件is here的Pastebin

    【讨论】:

      【解决方案8】:

      是的 - 我晚了 4 年。

      但我找到了一种无需创建外部脚本即可在一行中执行此操作的方法;通过从批处理文件中调用 powershell 命令。

      感谢 TessellatingHeckler - 无需输出到文本文件(我将 powershell 命令设置在一个变量中,因为它在 for 循环中的一长行中非常混乱)。

      @echo off
      set "psCommand=powershell -Command "$pword = read-host 'Enter Password' -AsSecureString ; ^
          $BSTR=[System.Runtime.InteropServices.Marshal]::SecureStringToBSTR($pword); ^
              [System.Runtime.InteropServices.Marshal]::PtrToStringAuto($BSTR)""
      for /f "usebackq delims=" %%p in (`%psCommand%`) do set password=%%p
      echo %password%
      

      最初我将其编写为输出到文本文件,然后从该文本文件中读取。但是上面的方法更好。在一个非常长,几乎无法理解的行中:

      @echo off
      powershell -Command $pword = read-host "Enter password" -AsSecureString ; $BSTR=[System.Runtime.InteropServices.Marshal]::SecureStringToBSTR($pword) ; [System.Runtime.InteropServices.Marshal]::PtrToStringAuto($BSTR) > .tmp.txt & set /p password=<.tmp.txt & del .tmp.txt
      echo %password%
      

      我将把它分解 - 你可以使用插入符号 ^ 将它分成几行,这样更好......

      @echo off
      powershell -Command $pword = read-host "Enter password" -AsSecureString ; ^
          $BSTR=[System.Runtime.InteropServices.Marshal]::SecureStringToBSTR($pword) ; ^
              [System.Runtime.InteropServices.Marshal]::PtrToStringAuto($BSTR) > .tmp.txt 
      set /p password=<.tmp.txt & del .tmp.txt
      echo %password%
      

      This article 解释了 powershell 命令在做什么;本质上,它使用Read-Host -AsSecureString 获取输入-以下两行将该安全字符串转换回纯文本,然后使用&gt;.tmp.txt 将输出(纯文本密码)发送到文本文件。然后将该文件读入变量并删除。

      【讨论】:

      • 最初的答案很好,但我认为现在应该是最终的答案
      • 这太棒了。但是它将纯文本密码保存到磁盘的方式让我感到不舒服。避免这样做,而是这样做:for /f "usebackq tokens=*" %%p in (``powershell -Command "$pword = read-host 'Enter Password' -AsSecureString ; $BSTR=[System.Runtime.InteropServices.Marshal]::SecureStringToBSTR($pword); [System.Runtime.InteropServices.Marshal]::PtrToStringAuto($BSTR)"``) do set password=%%p 然后echo %password%。注意。我无法让这条评论正确地转义反引号 - 在“powershell”之前和结束之前“)”是两个反引号,但应该是一个反引号。
      • @TessellatingHeckler 好主意,我已经更新了我的答案。您的建议的略微修改版本。谢谢。
      • @RegieBaguio 不,您需要启用 Powershell。看看下面 npocmaka 的 pure Batch 解决方案。它要复杂得多,但应该适合你。
      • 所以我在批处理文件中使用了 enabledelayedexpansion。问题是当我的密码中有一个感叹号时,除非我记得用插入符号转义它,否则它不需要。有什么想法吗?
      【解决方案9】:

      如果缺少源代码让您感到困扰,我还有另一种选择。

      @echo off
      for /f "delims=" %%p in ('ReadLine -h -p "Enter password: "') do set PWD=%%p
      echo You entered: %PWD%
      

      您可以从https://westmesatech.com/?page_id=49 获得它。包含源代码。

      【讨论】:

      • 注意:editenv32/editenv64 和 readline 实用程序已被开源 editenv 实用程序取代。
      【解决方案10】:

      1.纯批处理解决方案(ab)使用XCOPY 命令及其/P /L 开关找到here(对此进行一些改进可以be found here):

      :: Hidden.cmd
      ::Tom Lavedas, 02/05/2013, 02/20/2013
      ::Carlos, 02/22/2013
      ::https://groups.google.com/forum/#!topic/alt.msdos.batch.nt/f7mb_f99lYI
      
      
      @Echo Off
      :HInput
      SetLocal EnableExtensions EnableDelayedExpansion
      Set "FILE=%Temp%.\T"
      Set "FILE=.\T"
      Keys List >"%File%"
      Set /P "=Hidden text ending with Ctrl-C?: " <Nul
      Echo.
      Set "HInput="
      :HInput_
      For /F "tokens=1* delims=?" %%A In (
       '"Xcopy /P /L "%FILE%" "%FILE%" 2>Nul"'
      ) Do (
        Set "Text=%%B"
        If Defined Text (
          Set "Char=!Text:~1,1!"
          Set "Intro=1"
          For /F delims^=^ eol^= %%Z in ("!Char!") Do Set "Intro=0"
          Rem If press Intro
          If 1 Equ !Intro! Goto :HInput#
          Set "HInput=!HInput!!Char!"
        )
      )
      Goto :HInput_
      :HInput#
      Echo(!HInput!
      Goto :Eof 
      

      1.2 Another way based on replace command

      @Echo Off
      SetLocal EnableExtensions EnableDelayedExpansion
      
      Set /P "=Enter a Password:" < Nul
      Call :PasswordInput
      Echo(Your input was:!Line!
      
      Goto :Eof
      
      :PasswordInput
      ::Author: Carlos Montiers Aguilera
      ::Last updated: 20150401. Created: 20150401.
      ::Set in variable Line a input password
      For /F skip^=1^ delims^=^ eol^= %%# in (
      '"Echo(|Replace.exe "%~f0" . /U /W"') Do Set "CR=%%#"
      For /F %%# In (
      '"Prompt $H &For %%_ In (_) Do Rem"') Do Set "BS=%%#"
      Set "Line="
      :_PasswordInput_Kbd
      Set "CHR=" & For /F skip^=1^ delims^=^ eol^= %%# in (
      'Replace.exe "%~f0" . /U /W') Do Set "CHR=%%#"
      If !CHR!==!CR! Echo(&Goto :Eof
      If !CHR!==!BS! (If Defined Line (Set /P "=!BS! !BS!" <Nul
      Set "Line=!Line:~0,-1!"
      )
      ) Else (Set /P "=*" <Nul
      If !CHR!==! (Set "Line=!Line!^!"
      ) Else Set "Line=!Line!!CHR!"
      )
      Goto :_PasswordInput_Kbd
      

      2.使用HTA弹窗的密码提交者 . This is a hybrit .bat/jscript/mshta 文件,应另存为.bat:

      <!-- :
      :: PasswordSubmitter.bat
      @echo off
      for /f "tokens=* delims=" %%p in ('mshta.exe "%~f0"') do (
          set "pass=%%p"
      )
      
      echo your password is %pass%
      exit /b
      -->
      
      <html>
      <head><title>Password submitter</title></head>
      <body>
      
          <script language='javascript' >
              window.resizeTo(300,150);
              function entperPressed(e){
                      if (e.keyCode == 13) {
                          pipePass();
                      }
              }
              function pipePass() {
                  var pass=document.getElementById('pass').value;
                  var fso= new ActiveXObject('Scripting.FileSystemObject').GetStandardStream(1);
                  close(fso.Write(pass));
      
              }
          </script>
      
          <input type='password' name='pass' size='15' onkeypress="return entperPressed(event)" ></input>
          <hr>
          <button onclick='pipePass()'>Submit</button>
      
      </body>
      </html>
      

      3.A self-compiled .net hybrid .再次应保存为.bat 。与其他解决方案不同,它将创建/编译一个小的 .exe 文件,该文件将被调用(如果您愿意的话删除它)。还需要安装 .net 框架,但这不是问题:

      @if (@X)==(@Y) @end /* JScript comment
      @echo off
      setlocal enableDelayedExpansion
      
      for /f "tokens=* delims=" %%v in ('dir /b /s /a:-d  /o:-n "%SystemRoot%\Microsoft.NET\Framework\*jsc.exe"') do (
         set "jsc=%%v"
      )
      
      if not exist "%~n0.exe" (
          "%jsc%" /nologo /out:"%~n0.exe" "%~dpsfnx0"
      )
      
      for /f "tokens=* delims=" %%p in ('"%~n0.exe"') do (
          set "pass=%%p"
      )
      
      echo your password is !pass!
      
      endlocal & exit /b %errorlevel%
      
      */
      
      
      
      import System;
      
      
      
      var pwd = "";
      var key;
      
      Console.Error.Write("Enter password: ");
      
              do {
                 key = Console.ReadKey(true);
      
                 if ( (key.KeyChar.ToString().charCodeAt(0)) >= 20 && (key.KeyChar.ToString().charCodeAt(0) <= 126) ) {
                    pwd=pwd+(key.KeyChar.ToString());
                    Console.Error.Write("*");
                 }
      
                 if ( key.Key == ConsoleKey.Backspace && pwd.Length > 0 ) {
                     pwd=pwd.Remove(pwd.Length-1);
                     Console.Error.Write("\b \b");
                 }
      
      
              } while (key.Key != ConsoleKey.Enter);
              Console.Error.WriteLine();
              Console.WriteLine(pwd);
      

      【讨论】:

      • 我的 hacky 感觉很刺痛,尤其是在混合动力车上!
      • 第一个解决方案非常聪明 - 不错 +1。
      • 基于replace命令的2.1方法如果快速键入会漏键
      • @npocmaka 1.2 方法的最后一个版本(最后更新:20150405)在这里:consolesoft.com/batch/password_input/password_input.cmd
      • 太棒了。喜欢 mshta 解决方案。
      【解决方案11】:

      您可以将 ReadFormattedLine 子例程用于所有类型的格式化输入。例如,下面的命令读取一个 8 个字符的密码,在屏幕上显示星号,然后自动继续,无需回车:

      call :ReadFormattedLine password="********" /M "Enter password (8 chars): "
      

      这个子程序是用纯 Batch 编写的,所以它不需要任何额外的程序,并且它允许多种格式化输入操作,例如读取数字,将字母转换为大写等。您可以从Read a line with specific format 下载 ReadFormattedLine 子程序。


      编辑 2018-08-18输入“隐形”密码的新方法

      FINDSTR 命令有一个奇怪的错误,当此命令用于显示彩色字符并且此类命令的输出被重定向到 CON 设备时会发生这种错误。有关如何使用 FINDSTR 命令以彩色显示文本的详细信息,请参阅this topic

      当这种形式的 FINDSTR 命令的输出被重定向到 CON 时,在以所需颜色输出文本后会发生一些奇怪的事情:在它输出后的所有文本都作为“不可见”字符输出,尽管更准确的描述是文本输出为黑色背景上的黑色文本。如果您使用 COLOR 命令重置整个屏幕的前景色和背景色,则会出现原始文本。但是,当文本“不可见”时,我们可以执行 SET /P 命令,因此输入的所有字符都不会出现在屏幕上。

      @echo off
      setlocal
      
      set /P "=_" < NUL > "Enter password"
      findstr /A:1E /V "^$" "Enter password" NUL > CON
      del "Enter password"
      set /P "password="
      cls
      color 07
      echo The password read is: "%password%"
      

      【讨论】:

        【解决方案12】:

        更新:
        我添加了两个新方法,它们不是使用 cls 来隐藏输入,而是创建一个仅包含一行的新弹出窗口。

        缺点是一种方法(方法 2)会在注册表中留下垃圾 - “如果在没有适当权限的情况下运行”,而另一种方法(方法 3)会在脚本中附加一些垃圾。不用说它可以很容易地写入任何 tmp 文件并删除我只是想提出一个替代方案。

        限制:密码只能是字母数字 - 不能是其他字符!

        @echo off
        if "%1"=="method%choice%" goto :method%choice%
        ::::::::::::::::::
        ::Your code here::
        ::::::::::::::::::
        cls
        echo :::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
        echo ::::                   Batch script to prompt for password!                 :::
        echo :::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
        :choice
        echo.
        echo 1. First method
        echo.
        echo 2. Second method
        echo.
        echo 3. Third method
        echo.
        set/p choice=Choose a method: 
        if "%choice%" gtr "3" echo. & echo invalid option & echo. & pause & goto choice
        
        call :vars
            set options= %num%%smAlph%%cpAlph%
            set pwdLen=6
        
        if "%choice%" == "1" (
            set /p=Password: <nul 
            for /l %%i in (1,1,%pwdLen%) do call :password
        ) else (
            start /wait cmd /c call "%~f0" method%choice%
            )
        
        call :result%choice%
        
        
        ::just to see if it worked!
        echo.
        echo The Password you entered is: "%pwd%"&pause>nul
        
        ::::::::::::::::::
        ::More code here::
        ::::::::::::::::::
        exit /b
        
        
        
        
        
        :vars
        set num=1234567890
        set smAlph=abcdefghijklmnopqrstuvwxyz
        set cpAlph=ABCDEFGHIJKLMNOPQRSTUVWXYZ
            set pwd=
        goto :EOF
        
        
        :method2
        call :popUp
        setx result %pwd% >nul
        goto :EOF
        
        :method3
        call :popUp
            >> "%~f0" echo.
            >> "%~f0" echo :result%choice%
            >> "%~f0" echo set pwd=%pwd%
        goto :EOF
        
        :popUp
        title Password
        mode con lines=1 cols=30
        color 5a
        set /p=Password: <nul
        for /l %%i in (1,1,%pwdLen%) do call :password
        goto :EOF
        
        :password
        :: If you don't want case sensative remove "/cs" but remember to remove %cpAlph% from the %options%
        choice /c %options% /n /cs >nul
            call SET pwd=%pwd%%%options:~%errorlevel%,1%%
            set /p =*<nul
        GOTO :EOF
        
        
        :result2
        for /f "tokens=3" %%a in ('reg query hkcu\environment /v result') do set pwd=%%a
            setx result "" >nul
            reg delete hkcu\environment /v result /f >nul 2>&1
        :result1
        goto :EOF   
        ::You can delete from here whenever you want.
        

        更新: 我找到了sachadee's post to be perfect,并在其中添加了我的“弹出式”怪癖。

        @Echo Off  
          SetLocal EnableDelayedExpansion
          if "%1"==":HInput" goto :HInput
          set r=r%random%
          start /wait cmd /c call "%~f0" :HInput
        
        For /f "tokens=2,13 delims=, " %%a in (
            'tasklist /v /fo csv /fi "imagename eq cmd.exe"
            ^|findstr /v "Windows\\system32\\cmd.exe"
            ^|findstr "set /p=%r%"'
             ) do (
                set pid=%%a
                set Line=%%b
                set Line=!Line:%r%=!
                set Line=!Line:~,-2!
                )       
        taskkill /pid %pid:"=%>nul
          goto :HIEnd
        
        
          :HInput
          SetLocal DisableDelayedExpansion
          title Password
          mode con lines=2 cols=30
        
        Echo Enter your Code :
           Set "Line="
           For /F %%# In (
           '"Prompt;$H&For %%# in (1) Do Rem"'
           ) Do Set "BS=%%#"
        
          :HILoop
           Set "Key="
           For /F "delims=" %%# In (
           'Xcopy /W "%~f0" "%~f0" 2^>Nul'
           ) Do If Not Defined Key Set "Key=%%#"
           Set "Key=%Key:~-1%"
           SetLocal EnableDelayedExpansion
           If Not Defined Key start /min cmd /k mode con lines=1 cols=14 ^&set/p %r%!Line!=&exit
          If %BS%==^%Key% (Set /P "=%BS% %BS%" <Nul
           Set "Key="
           If Defined Line Set "Line=!Line:~0,-1!"
           ) Else Set /P "=*" <Nul
           If Not Defined Line (EndLocal &Set "Line=%Key%"
           ) Else For /F delims^=^ eol^= %%# In (
           "!Line!") Do EndLocal &Set "Line=%%#%Key%"
          Goto :HILoop
        
          :HIEnd
           Echo(
        Echo Your code is :  "!Line!"
           Pause
           Goto :Eof
        

        【讨论】:

          【解决方案13】:
          @echo off
          color 0f
          MODE CON COLS=132 LINES=50
          :start
          cls
          choice /C ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789!?.# /N /CS /M Please enter your password to continue. (Valid characters include all letters, numbers, and ! ? .) Press # to submit: 
          SET ecode=%ERRORLEVEL%
          IF %ecode% EQU 66 goto submit
          IF %ecode% EQU 1 SET out=A
          IF %ecode% EQU 2 SET out=B
          IF %ecode% EQU 3 SET out=C
          IF %ecode% EQU 4 SET out=D
          IF %ecode% EQU 5 SET out=E
          IF %ecode% EQU 6 SET out=F
          IF %ecode% EQU 7 SET out=G
          IF %ecode% EQU 8 SET out=H
          IF %ecode% EQU 9 SET out=I
          IF %ecode% EQU 10 SET out=J
          IF %ecode% EQU 11 SET out=K
          IF %ecode% EQU 12 SET out=L
          IF %ecode% EQU 13 SET out=M
          IF %ecode% EQU 14 SET out=N
          IF %ecode% EQU 15 SET out=O
          IF %ecode% EQU 16 SET out=P
          IF %ecode% EQU 17 SET out=Q
          IF %ecode% EQU 18 SET out=R
          IF %ecode% EQU 19 SET out=S
          IF %ecode% EQU 20 SET out=T
          IF %ecode% EQU 21 SET out=U
          IF %ecode% EQU 22 SET out=V
          IF %ecode% EQU 23 SET out=W
          IF %ecode% EQU 24 SET out=X
          IF %ecode% EQU 25 SET out=Y
          IF %ecode% EQU 26 SET out=Z
          IF %ecode% EQU 27 SET out=a
          IF %ecode% EQU 28 SET out=b
          IF %ecode% EQU 29 SET out=c
          IF %ecode% EQU 30 SET out=d
          IF %ecode% EQU 31 SET out=e
          IF %ecode% EQU 32 SET out=f
          IF %ecode% EQU 33 SET out=g
          IF %ecode% EQU 34 SET out=h
          IF %ecode% EQU 35 SET out=i
          IF %ecode% EQU 36 SET out=j
          IF %ecode% EQU 37 SET out=k
          IF %ecode% EQU 38 SET out=l
          IF %ecode% EQU 39 SET out=m
          IF %ecode% EQU 40 SET out=n
          IF %ecode% EQU 41 SET out=o
          IF %ecode% EQU 42 SET out=p
          IF %ecode% EQU 43 SET out=q
          IF %ecode% EQU 44 SET out=r
          IF %ecode% EQU 45 SET out=s
          IF %ecode% EQU 46 SET out=t
          IF %ecode% EQU 47 SET out=u
          IF %ecode% EQU 48 SET out=v
          IF %ecode% EQU 49 SET out=w
          IF %ecode% EQU 50 SET out=x
          IF %ecode% EQU 51 SET out=y
          IF %ecode% EQU 52 SET out=z
          IF %ecode% EQU 53 SET out=0
          IF %ecode% EQU 54 SET out=1
          IF %ecode% EQU 55 SET out=2
          IF %ecode% EQU 56 SET out=3
          IF %ecode% EQU 57 SET out=4
          IF %ecode% EQU 58 SET out=5
          IF %ecode% EQU 59 SET out=6
          IF %ecode% EQU 60 SET out=7
          IF %ecode% EQU 61 SET out=8
          IF %ecode% EQU 62 SET out=9
          IF %ecode% EQU 63 SET out=!
          IF %ecode% EQU 64 SET out=?
          IF %ecode% EQU 65 SET out=.
          SET code=%out%
          SET show=*
          :loop
          cls
          choice /C ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789!?.# /N /CS /M Please enter your password to continue. (Valid characters include all letters, numbers, and ! ? .) Press # to submit: %code%
          SET ecode=%ERRORLEVEL%
          IF %ecode% EQU 66 goto submit
          IF %ecode% EQU 1 SET out=A
          IF %ecode% EQU 2 SET out=B
          IF %ecode% EQU 3 SET out=C
          IF %ecode% EQU 4 SET out=D
          IF %ecode% EQU 5 SET out=E
          IF %ecode% EQU 6 SET out=F
          IF %ecode% EQU 7 SET out=G
          IF %ecode% EQU 8 SET out=H
          IF %ecode% EQU 9 SET out=I
          IF %ecode% EQU 10 SET out=J
          IF %ecode% EQU 11 SET out=K
          IF %ecode% EQU 12 SET out=L
          IF %ecode% EQU 13 SET out=M
          IF %ecode% EQU 14 SET out=N
          IF %ecode% EQU 15 SET out=O
          IF %ecode% EQU 16 SET out=P
          IF %ecode% EQU 17 SET out=Q
          IF %ecode% EQU 18 SET out=R
          IF %ecode% EQU 19 SET out=S
          IF %ecode% EQU 20 SET out=T
          IF %ecode% EQU 21 SET out=U
          IF %ecode% EQU 22 SET out=V
          IF %ecode% EQU 23 SET out=W
          IF %ecode% EQU 24 SET out=X
          IF %ecode% EQU 25 SET out=Y
          IF %ecode% EQU 26 SET out=Z
          IF %ecode% EQU 27 SET out=a
          IF %ecode% EQU 28 SET out=b
          IF %ecode% EQU 29 SET out=c
          IF %ecode% EQU 30 SET out=d
          IF %ecode% EQU 31 SET out=e
          IF %ecode% EQU 32 SET out=f
          IF %ecode% EQU 33 SET out=g
          IF %ecode% EQU 34 SET out=h
          IF %ecode% EQU 35 SET out=i
          IF %ecode% EQU 36 SET out=j
          IF %ecode% EQU 37 SET out=k
          IF %ecode% EQU 38 SET out=l
          IF %ecode% EQU 39 SET out=m
          IF %ecode% EQU 40 SET out=n
          IF %ecode% EQU 41 SET out=o
          IF %ecode% EQU 42 SET out=p
          IF %ecode% EQU 43 SET out=q
          IF %ecode% EQU 44 SET out=r
          IF %ecode% EQU 45 SET out=s
          IF %ecode% EQU 46 SET out=t
          IF %ecode% EQU 47 SET out=u
          IF %ecode% EQU 48 SET out=v
          IF %ecode% EQU 49 SET out=w
          IF %ecode% EQU 50 SET out=x
          IF %ecode% EQU 51 SET out=y
          IF %ecode% EQU 52 SET out=z
          IF %ecode% EQU 53 SET out=0
          IF %ecode% EQU 54 SET out=1
          IF %ecode% EQU 55 SET out=2
          IF %ecode% EQU 56 SET out=3
          IF %ecode% EQU 57 SET out=4
          IF %ecode% EQU 58 SET out=5
          IF %ecode% EQU 59 SET out=6
          IF %ecode% EQU 60 SET out=7
          IF %ecode% EQU 61 SET out=8
          IF %ecode% EQU 62 SET out=9
          IF %ecode% EQU 63 SET out=!
          IF %ecode% EQU 64 SET out=?
          IF %ecode% EQU 65 SET out=.
          SET code=%code%%out%
          SET show=%show%*
          goto loop
          :submit
          cls
          SET password=%code%
          IF %password% EQU 0cZrocks! SET result=1
          IF ELSE SET result=2
          IF %result% EQU 1 echo password correct
          IF %result% EQU 2 echo password incorrect
          timeout /T 2 /NOBREAK >nul
          cls
          IF %result% EQU 1 goto end
          IF ELSE goto start
          :end
          

          【讨论】:

          • 你没有解释代码,你只是复制了那个代码。这不是一个好方法,因为您需要刷新屏幕并且密码需要 x 个字符长。
          【解决方案14】:

          如果你安装了 Python,你可以使用:

          for /f "delims=" %%A in ('python -c "import getpass; print(getpass.getpass('Enter the CVS password: '));"') do @set CVSPASS=%%A
          echo PASS: %CVSPASS%
          

          输出:

          Enter the CVS password:
          PASS: 123
          

          【讨论】:

            【解决方案15】:

            我编写了一个名为 editenv 的开源程序,它取代了我旧的 editv32/editv64 实用程序:

            https://github.com/Bill-Stewart/editenv

            --maskinput (-m) 选项[*] 可让您隐藏(屏蔽)键入的输入并具有可配置的字符(默认字符为 *);例如:

            editenv -m -p "Password: " PWD
            

            --prompt (-p) 选项可让您指定输入提示。上面会显示一个Password: 提示并等待你输入一些东西。键入的字符将显示为*。按 Ctrl+C 将结束程序,退出代码为 1223。

            下载地址:

            https://github.com/Bill-Stewart/editenv/releases

            [*] 请注意,--maskinput (-m) 选项是不安全 -- 输入的字符串在环境中以纯文本形式输入。此功能仅为方便起见。

            【讨论】:

              【解决方案16】:

              您可以将前景色设置为黑色,例如:

              :: see https://stackoverflow.com/questions/33293220/what-is-the-fastest-color-function-in-batch
              @echo off
              for /F %%a in ('echo prompt $E ^| cmd') do set "ESC=%%a"
              set color_white=%ESC%[37m
              set color_black=%ESC%[30m
              echo(
              set /p user=Username:
              set /p pass=password:%color_black%
              echo %color_white%
              echo blablablba
              

              享受!!! C.

              【讨论】:

              • 请注意:仅适用于 echo off,否则 set 命令已更改颜色。当然,当背景颜色已经是黑色时(默认情况下,但你不能依赖它)。不错的发现(尽管我怀疑它在 2009 年会起作用)
              【解决方案17】:

              好的,所以我刚刚找到了一个非常体面的工作来解决这个问题。 CMDKEY 适用于 Windows 7+ 并允许您从 cmd 提示符将详细信息输入到 Windows 凭据管理器中,如果您使用 /pass 开关,它会提供自己的密码输入而不会暴露密码。它不会在您键入时显示 *****,但密码是隐藏的。

              下面的脚本正常请求用户名并创建一个名为“%username%”的变量,然后检查凭据管理器是否已经有目标服务器的条目。如果是这样,它只是将驱动器映射到用户名并且不请求密码。如果没有条目,则使用 CMDKEY 提示输入密码并将其存储在凭据管理器中。

                  set /p username="Enter School Username: "
                  CMDKEY /list:SERVERNAME | FIND "NONE" > nul 2>&1
                  IF %ERRORLEVEL% NEQ 0 GOTO MAPDRIVES
                  CMDKEY /ADD:SERVERNAME /username:%username% /pass
                  :MAPDRIVES
                  NET USE Y: \\SERVERNAME\SHARE\%username%
              

              【讨论】:

                【解决方案18】:

                很遗憾,我无法得到@unclemeat 的答案,无法在 Windows 10 21H1 系统上工作。我刚刚得到:[System.Runtime.InteropServices.Marshal]::PtrToStringAuto($BSTR)"" was unexpected at this time.

                但他让我走上了正轨。

                所以这是我的变种:

                脚本顶部的配置:

                @ECHO OFF
                :: Don't leak variables to command shell
                SETLOCAL
                
                    REM service user for backend services - comment out to default to LOCALSYSTEM
                SET WINDOWS_SVC_USERNAME=svcadmin
                

                检查管理员权限和创建服务后的底部某处:

                SETLOCAL ENABLEDELAYEDEXPANSION
                
                :: Read password for service user
                IF DEFINED WINDOWS_SVC_USERNAME (
                    SET PWR=powershell -Command "$secureString = Read-Host 'Enter password for service user \".\%WINDOWS_SVC_USERNAME%\"' -AsSecureString -ErrorAction Stop; $ptr = [System.Runtime.InteropServices.Marshal]::SecureStringToGlobalAllocUnicode($secureString); $plain = [System.Runtime.InteropServices.Marshal]::PtrToStringUni($ptr); [System.Runtime.InteropServices.Marshal]::ZeroFreeGlobalAllocUnicode($ptr); Write-Host $plain;"
                    FOR /F "usebackq delims=" %%P IN (`!PWR!`) DO SET WINDOWS_SVC_PASSWORD=%%P
                    IF DEFINED WINDOWS_SVC_PASSWORD (
                        IF ["!WINDOWS_SVC_PASSWORD!"] NEQ [""] (
                            IF ["!WINDOWS_SVC_PASSWORD!"] NEQ [" "] (
                                :: The password is now set correctly
                                ECHO "Using ".\%WINDOWS_SVC_USERNAME%" as service user..."
                                sc config  prod!WINDOWS_SVC_INFIX!rest!INDEX! obj= ".\!WINDOWS_SVC_USERNAME!" password= "!WINDOWS_SVC_PASSWORD!"
                            ) ELSE (
                                ECHO "ERROR -- Password possibly empty or PowerShell threw an exception."
                                SET "WINDOWS_SVC_USERNAME="
                            )
                        ) ELSE (
                            ECHO "ERROR -- Could not retrieve password! Password is possibly empty."
                            SET "WINDOWS_SVC_USERNAME="
                        )
                    ) ELSE (
                        ECHO "ERROR -- No password given or PowerShell is not available."
                        SET "WINDOWS_SVC_USERNAME="
                    )
                ) ELSE (
                    ECHO "No service user specified - keeping default "LOCALSYSTEM" user..."
                )
                

                当然,sc config prod!WINDOWS_SVC_INFIX!rest!INDEX! 只是从我的 for 循环中复制而来,需要根据您的具体情况进行调整。 请改用ECHO password read: "!WINDOWS_SVC_PASSWORD!" 进行调试。

                这还没有在野外测试,所以请小心处理。

                【讨论】:

                  猜你喜欢
                  • 2013-03-04
                  • 2012-06-27
                  • 1970-01-01
                  • 2017-03-23
                  • 1970-01-01
                  • 1970-01-01
                  • 1970-01-01
                  相关资源
                  最近更新 更多