如何使用特定的按键输入中断 CMD 批处理文件中的循环?

问题描述 投票:0回答:3

整个想法是这样的: 我有一个菜单可以在批处理文件中测试 ping 不同的 DNS 服务器,如下所示:

:MainMenu
ECHO 1. DNS Server 1
ECHO 2. DNS Server 2

现在,当用户选择上述选项之一时,该过程将开始

ping
所选服务器,在本例中我使用 google DNS
8.8.8.8
:

:loopStarter
ECHO ***AUTO PING MODE IS ENABLED***
ECHO Pinging...
ping 8.8.8.8

CLS

GOTO loopStarter

正如您所看到的,这堆代码创建了一个循环,并且

pings
服务器永远不会停止,

但是

我想通过输入一个键(任意键)来停止循环,将我带回到

:MainMenu

============

我已经看到并测试了很多答案,例如Here,但不幸的是我不理解代码或者它与我的问题无关。

如果有人能指导我,我将不胜感激。

loops batch-file cmd break
3个回答
2
投票

一个简单的并行线程示例。
:key_Detector 线程等待按键,然后删除 notification_file
:ping_test 执行 ping,然后检查 notification_file 是否存在,如果仍然存在,则将重复循环。

线程由管道的两个子实例启动。
这看起来有点复杂,因为你不能直接在管道内部调用标签,它只是启动自己的程序并在开始时使用蹦床跳转到标签。

@echo off
REM *** This is a trampoline to jump to a function when a child process shall be invoked
for /F "tokens=3 delims=:" %%L in ("%~0") do goto %%L

set "notification_file=%temp%\keypress.tmp"

echo dummy > "%notification_file%"
call "%~d0\:key_detector:\..%~pnx0" | call "%~d0\:ping_test:\..%~pnx0"
exit /b


:ping_test
ping -n 2 8.8.8.8 
if not exist "%notification_file%" exit /b
goto :ping_test

:key_detector
for /F "tokens=1 skip=1 eol=" %%C in ('"replace /w ? . < con"') do @(
    set "key=%%C"
    del %notification_file%
)

exit /b

1
投票

基于这里找到的创建动态菜单的方法,您可以创建类似的东西:


@echo off
:menuLOOP
Title Pinging some DNS
Color 9E & Mode 80,15
::===========================================================================
echo(
echo(
echo(       ***************************** Menu ******************************
echo(
@for /f "tokens=2* delims=_ " %%A in ('"findstr /b /c:":menu_" "%~f0""') do (
echo            %%A  %%B)
echo(
echo(       *****************************************************************
echo( Make A Selection And Hit ENTER to Ping or simply hit ENTER to quit:
Set /p Selection= || GOTO :EOF
echo( & call :menu_[%Selection%]
GOTO:menuLOOP
::===========================================================================
:menu_[1] Ping DNS Server 1
Cls
ECHO( Pinging...
ping 8.8.8.8
echo( & echo( Type any key to return to the Main Menu
pause>nul
Goto:menuLoop
::---------------------------------------------------------------------------
:menu_[2] Ping DNS Server 2
Cls
ECHO( Pinging...
ping 8.8.4.4
echo( & echo( Type any key to return to the Main Menu
pause>nul
Goto:menuLoop
::---------------------------------------------------------------------------

0
投票

无需深入了解我用于 ping 测试的全部 80 多行代码,这里是您正在寻找的中断的简短答案。

:loopStarter
ECHO ***AUTO PING MODE IS ENABLED***
ECHO Pinging...
ping 8.8.8.8

choice /c xn /n /t 1 /d n >nul
if %errorlevel% EQU 1 goto :EOF

CLS

GOTO loopStarter

使用

choice
命令,
/c
指定允许的字符,在本例中为 x 和 n。
/n
告诉它不要将选项列表写入屏幕。
/t
指示在做出默认选择之前要等待多少秒,在本例中为 1。
/d
指定默认选择,在本例中为 n,这是第二个选项。并且
>nul
使得整个命令不会向屏幕写入任何内容。

然后

if
语句检查选项列表中的第一个字符是否被按下,如果是则中断循环。

您可以列出选项列表中的每个字符,但您还必须为每个字符创建一个

if
语句,并仍然保留一个作为默认选项,以便在您不想中断循环时继续循环。我只是发现使用特定字符来进行中断更容易。

此外,根据您使用的循环,这可能不可行,因为它会导致循环之间有 1 秒的延迟,但我发现对于 Pings,这不是问题。

© www.soinside.com 2019 - 2024. All rights reserved.