【问题标题】:How to ask for batch file user input with a timeout如何在超时的情况下请求批处理文件用户输入
【发布时间】:2012-09-08 14:04:26
【问题描述】:

所以我试图在 set 命令下的一个 if 语句中添加一个计时器,但我不确定该命令是什么。该脚本将启动并等待三十分钟,然后重新启动 PC 或等待用户输入以在那时输入或取消它。所以我设置了“立即重启”和“取消”的两个 if 语句,但现在我需要一个 if 语句让它从执行我的重启命令前的 30 分钟开始倒计时。此外,如果有人知道如何在那里添加一个可视计时器,显示还剩多少时间,那将是一个加号。谢谢大家!!!

@Echo off

:START

set /p answer=PC WILL RESTART IN 30 MINUTES, PRESS N TO RESTART NOW OR C TO CANCEL

if "%answer%"=="n" (GOTO Label1)
if "%answer%"=="c" (GOTO Label2)
if "TIMER GOES HERE" "==" (GOTO Label1)

:Label1

shutdown -r -t 60 -f

:Label2 

exit

【问题讨论】:

    标签: if-statement batch-file timer shutdown restart


    【解决方案1】:

    与休眠类似。

    @echo off
    setlocal enableDelayedExpansion
    for /l %%N in (600 -1 1) do (
      set /a "min=%%N/60, sec=%%N%%60, n-=1"
      if !sec! lss 10 set sec=0!sec!
      cls
      choice /c:CN1 /n /m "HIBERNATE in !min!:!sec! - Press N to hibernate Now, or C to Cancel. " /t:1 /d:1
      if not errorlevel 3 goto :break
    )
    cls
    echo HIBERNATE in 0:00 - Press N to hibernate Now, or C to Cancel.
    :break
    if errorlevel 2 (%windir%\System32\rundll32.exe powrprof.dll,SetSuspendState Hibernate) else echo Hibernate Canceled
    

    【讨论】:

    • 你能解释一下它是如何工作的吗?顺便说一句很酷的倒计时。
    • @workoverflow 循环从 600 秒倒计时,每次 -1 直到 1。从秒计算分钟和秒。只需用 0 填充几秒钟。 min 和 sec 被传递给选择字符串。 /c:CN1 将 C 和 N 个字符从输入映射到 errorlevel。如果 errorlevel 为 1 或 2,则用户按下一个键并跳转到中断。错误级别 2 是 N 所以休眠。
    【解决方案2】:

    我推荐使用CHOICE.EXE,它是大多数Windows版本的标准配置(除了Windows NT、2000和XP,它曾经可以从微软的网站上下载,但他们似乎忽略了this*一个在他们的 ftp 站点上。)并且易于使用。

    @Echo off
    :START
    set waitMins=30
    
    echo PC WILL RESTART IN %waitMins% MINUTES: Press N to restart [N]ow or C to [C]ancel
    :: Calculate Seconds
    set /a waitMins=waitMins*60
    :: Choices are n and c, default choice is n, timeout = 1800 seconds
    choice /c nc /d n /t %waitMins%
    
    :: [N]ow = 1; [C]ancel = 2
    goto Label%errorlevel%
    
    :Label1
    
    shutdown -r -t 60 -f
    :: Make sure that the process doesn't fall through to Lable2
    goto :eof
    
    :Label2 
    exit
    

    只需CHOICE.EXE 就是这样工作的......

    choice
    

    ...和...相同

    choice /c yn
    

    ...两者都会显示...

    [Y,N]?
    

    ...两者都将等待用户按下YN

    Choice 将结果存储在 %errorlevel% 中。 Y=1,N=2。

    我提供的代码利用了默认的/D <choice> 和超时/T <seconds> 选项。

    例如...

    choice /c yn /d y /t 5
    

    ...让用户选择 Y 或 N,将等待 5 秒然后自动选择默认选项 Y,导致 %ERRORLEVEL%==1。

    另一个例子是……

    choice /c abcdef /m "Make a choice. "
    

    ...它显示...

    Make a choice. [A,B,C,D,E,F]? 
    

    ...和...

    A = %ERRORLEVEL% = 1
    B = %ERRORLEVEL% = 2
    C = %ERRORLEVEL% = 3
    D = %ERRORLEVEL% = 4
    E = %ERRORLEVEL% = 5
    F = %ERRORLEVEL% = 6
    

    没有ERRORLEVEL 0。

    有关choice 使用的更多信息,请在命令提示符处键入CHOICE /?


    *注意CHOICE.EXE 的版本我提供了一个链接,使用略有不同的命令,但提供相同的功能。

    【讨论】:

      【解决方案3】:

      这是一个非常简单的 Vista 和 Windows 7 解决方案,它提供了超时功能,但不提供视觉倒计时。

      @echo off
      choice /c:CN /n /m "PC will restart in 30 minutes. Press N to restart Now, or C to Cancel" /t:1800 /d:N
      if errorlevel 2 (shutdown -r -t 60 -f) else echo Restart Canceled
      

      这是一个更复杂的 Vista 和 Windows 7 解决方案,它提供视觉倒计时,但它每秒都会清除控制台窗口。另外时间可能有点不对。

      @echo off
      setlocal enableDelayedExpansion
      for /l %%N in (1800 -1 1) do (
        set /a "min=%%N/60, sec=%%N%%60, n-=1"
        if !sec! lss 10 set sec=0!sec!
        cls
        choice /c:CN1 /n /m "PC will restart in !min!:!sec! - Press N to restart Now, or C to Cancel. " /t:1 /d:1
        if not errorlevel 3 goto :break
      )
      cls
      echo PC will restart in 0:00 - Press N to restart Now, or C to Cancel.
      :break
      if errorlevel 2 (shutdown -r -t 60 -f) else echo Restart Canceled
      

      如果您需要 XP 解决方案,那么我认为您需要下载一个非本地命令行工具,该工具要求输入具有超时功能,或者切换到 VBScript 或 JScript。

      编辑

      通过使用 James K 在他的回答中提供的CHOICE.EXE download from the Microsoft FTP site,可以调整上述两个脚本以在 XP 上运行。

      该版本的 CHOICE 语法略有不同。

      要改编我的第一个脚本,请使用:

      choice /c:CN /n /t:N,1800 "PC will restart in 30 minutes. Press N to restart Now, or C to Cancel"
      

      要调整我的第二个脚本,请使用:

      choice /c:CN1 /n /t:1,1 "PC will restart in !min!:!sec! - Press N to restart Now, or C to Cancel. "
      


      编辑 - 这是一个与 XP 兼容的粗略 VBS 解决方案

      Set objShell = CreateObject("WScript.Shell")
      for i = 30 to 1 step -1
        if i=1 then unit=" minute" else unit=" minutes"
        rtn = objShell.Popup ( _
          "The machine would like to Restart."&VbCrLf&VbCrLf& _
          "Click OK to restart now"&VbCrLf& _
          "Click Cancel or the [X] close button to abort the restart"&VbCrLf& _
          "Do nothing and the machine will restart in "&i&unit, _
          60, "Restart in "&i&unit, 1+48 _
        )
        if rtn <> -1 then exit for
      next
      if rtn <> 2 then objShell.Run "shutdown -r -f"
      

      我认为您可以使用 HTA 提供更优雅的 VBS 解决方案,但工作量很大,而且我对这项技术了解不多。

      【讨论】:

      • 有没有办法在不使用选择命令的情况下做到这一点?我的大多数 PC 将是 XP 机器,我真的不想到处使用它们并从 Microsoft 下载该选择命令。
      • @MattP - 正如我在回答中已经说过的,您可以使用 VBS,但不能使用本机批处理。请参阅我对 VBS 解决方案的更新答案。
      【解决方案4】:

      我将使用此代码使脚本暂停指定的毫秒数:

      PING 1.1.1.1 -n 1 -w <milliseconds> >NUL 
      

      这将在&lt;milliseconds&gt; 过去后向 IP 地址1.1.1.1 发送 1 个 ping。并且ping 命令的输出将被解除为 NUL。

      【讨论】:

      • 这有什么帮助?如果用户在超时期限内没有响应,OP 需要提示用户输入并自动使用默认值。唯一可以执行此操作的本机批处理命令是 CHOICE,但这不是 XP 的本机命令。
      • 在我回答了他们原来的问题后,他们改变了他们的要求。
      【解决方案5】:

      我推荐 SPC_75 的这个脚本 虽然它是一个 .vbs 文件,并且用于休眠,但它很容易修改为休眠或关机。

      '//*******************************************
      '//hibernate.vbs
      '//Purpose: Count Down to action (Hibernate)
      '//Tested on Server 2008, Win 7 64bit, and XP
      '//Author: SPC_75 
      '//Revision 1.3
      '//Date: 1/09/2011
      '//*******************************************
      
      Option Explicit
      Dim timeout, objShell, intReturn
      Const wshOk = 1
      Const wshOkDialog = 0
      'Const wshIcon = 16 '/critical
      'Const wshIcon = 32 '/question
      Const wshIcon = 48 '/exclamation
      'Const wshIcon = 64 '/information
      
      timeout = 30 '/Timeout in seconds
      
      Set objShell = CreateObject("Wscript.Shell")
        Do Until timeout = 0
          timeout = timeout - 1
          intReturn = objShell.Popup(vbCrlf &"Hibernation about to initiate. Abort?"&vbCrlf & vbCrlf & vbCrlf & vbCrlf & "Time until hibernation : " & timeout, 1, "Hibernation", wshOkDialog + wshIcon + 4096)
          If intReturn = wshOk Then
              Wscript.Quit
          End If
        loop
        objShell.Run "powercfg /hibernate on"
        objShell.Run "shutdown -h"
        objShell.Run "rundll32 powrprof.dll,SetSuspendState Hibernate"  '/XP specific Hibernation command
      set objShell = nothing
      
      '//EOF
      

      完美配合警告和超时。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2018-09-04
        • 1970-01-01
        • 1970-01-01
        • 2013-07-21
        • 1970-01-01
        相关资源
        最近更新 更多