如何自动关闭 Windows 控制台(以编程方式将 CTRL+C 发送到控制台)?
How to close Windows console automatically (send CTRL+C to console programatically)?
我有两个 windows 批处理脚本,script1.bat
和 script2.bat
。 script2.bat
从 script1.bat
开始。
script1.bat
:
...
start call script2.bat
...
script2.bat
必须在用户关闭 script1.bat
的控制台时关闭(换句话说,script2.bat
并且它的控制台应该在 script1.bat
关闭时自动关闭).但是 script2.bat
不应该被杀死,它应该被终止,因为 script2.bat
必须释放数据库连接。我指的是使用 kill
和 terminate
词的 unix 信号术语。所以 scrip2.bat
不应立即终止,它应该以允许进程执行良好终止的方式终止,释放资源并在适当时保存状态。
我是为unix系统做的,解决方法如下。
script1.sh
:
...
sh script2.sh > /dev/null 2>&1 &
script2_pid="$!"
trap 'kill -15 $script2_pid' EXIT HUP TERM INT KILL
...
如何在 Windows 上制作?
====编辑====
我觉得我的问题对大家来说不是很清楚所以我想澄清一下。
我有 java 应用程序连接到 JBoss 应用程序服务器。它现在已经过测试,我需要以非常方便的方式启动它们。我准备了启动客户端应用程序和 JBoss 应用程序的批处理脚本 (script1.bat
)。这个脚本还做其他事情,比如设置环境变量。所以 script2.bat
实际上是一个 Jboss standalone.bat
文件。我不想编辑这个文件。
script1.bat
是我的脚本,它设置环境变量,启动 JBoss 并启动我的 java 应用程序。
我的脚本(script1.bat):
...
set environment variable
...
REM start jboss
start standalone.bat
REM start my java application
java ...
当用户关闭 Java 应用程序时,JBoss 也应该关闭。我只是为了方便测试人员才需要它,而且我知道在生产环境中它应该以另一种方式工作。
我不知道如何在用户关闭我的 java 客户端应用程序后自动终止 JBoss。 JBoss 连接到 H2 数据库并在其上创建锁,因此如果 JBoss 将立即被终止,那么数据库锁仍然存在。如果 JBoss 进程收到 CTRL+C,它会正确终止(删除数据库锁)。我想自动设置,在用户关闭 java 客户端应用程序后,JBoss 必须关闭,因为它收到 CTRL+C。
我不知道如何在 Windows 上执行此操作。但我是在 linux 上做的,我将我的代码添加到这个问题中。
抱歉,您的脚本毫无意义。 start call script2.bat
?? start
和 call
的组合是胡说八道。您使用其中之一,但不能同时使用两者。
此外,我不得不让你失望。无法关闭控制台,只能保留代码 运行。您甚至无法在 Windows 中启动隐藏控制台。关闭控制台将立即停止代码的执行。
编辑:
现在我明白你在问什么了。使用
开始你的第一个脚本
start "somename" script1.bat
这将在控制台中以 "somename" 作为 window 标题启动 script1。
在第二个脚本中你可以使用这个:
:WORKING
REM Do some stuff here
REM and here
REM and here
FOR /f "tokens=*" %%A IN ('tasklist^ /v^| findstr /i /c:"somename"') DO GOTO WORKING
REM shutdown part
REM close db connections
REM exit script2
这部分将检查标题中带有 "somename" 的控制台是否为 运行,如果是,则重新进入循环。在循环结束时,它总是检查 script1 是否仍然处于活动状态。一旦找不到,代码就会继续到关闭部分。
如果你只想等待 script1 终止你可以使用 PING -n 5 127.0.0.1 > NUL
作为 5(或更长,只需替换 5 ^^)第二次超时以避免 busy-waiting:
:WORKING
PING -n 5 127.0.0.1 > NUL
FOR /f "tokens=*" %%A IN ('tasklist^ /v^| findstr /i /c:"somename"') DO GOTO WORKING
REM shutdown part
REM close db connections etc.
REM exit script2
如果在 JBoss 中启用了 CLI,那么 JBoss 可以通过 CLI 关闭。以下批处理显示如何关闭 JBoss
...
set environment variable
...
REM start jboss
start "UNIQUE_NAME" path_to_JBoss\bin\standalone.bat -c standalone.xml
REM start java application
java ...
REM shutdown JBoss by CLI
call path_to_JBoss\bin\jboss-cli.bat --connect ":shutdown"
REM it is just in case. If CLI did not shutdown JBoss, then following line kills JBoss without release of resource.
FOR /f "TOKENS=1,2,*" %%a IN ('tasklist^ /FI "WINDOWTITLE eq UNIQUE_NAME*" /nh') DO taskkill /pid %%b
我有两个 windows 批处理脚本,script1.bat
和 script2.bat
。 script2.bat
从 script1.bat
开始。
script1.bat
:
...
start call script2.bat
...
script2.bat
必须在用户关闭 script1.bat
的控制台时关闭(换句话说,script2.bat
并且它的控制台应该在 script1.bat
关闭时自动关闭).但是 script2.bat
不应该被杀死,它应该被终止,因为 script2.bat
必须释放数据库连接。我指的是使用 kill
和 terminate
词的 unix 信号术语。所以 scrip2.bat
不应立即终止,它应该以允许进程执行良好终止的方式终止,释放资源并在适当时保存状态。
我是为unix系统做的,解决方法如下。
script1.sh
:
...
sh script2.sh > /dev/null 2>&1 &
script2_pid="$!"
trap 'kill -15 $script2_pid' EXIT HUP TERM INT KILL
...
如何在 Windows 上制作?
====编辑====
我觉得我的问题对大家来说不是很清楚所以我想澄清一下。
我有 java 应用程序连接到 JBoss 应用程序服务器。它现在已经过测试,我需要以非常方便的方式启动它们。我准备了启动客户端应用程序和 JBoss 应用程序的批处理脚本 (script1.bat
)。这个脚本还做其他事情,比如设置环境变量。所以 script2.bat
实际上是一个 Jboss standalone.bat
文件。我不想编辑这个文件。
script1.bat
是我的脚本,它设置环境变量,启动 JBoss 并启动我的 java 应用程序。
我的脚本(script1.bat):
...
set environment variable
...
REM start jboss
start standalone.bat
REM start my java application
java ...
当用户关闭 Java 应用程序时,JBoss 也应该关闭。我只是为了方便测试人员才需要它,而且我知道在生产环境中它应该以另一种方式工作。 我不知道如何在用户关闭我的 java 客户端应用程序后自动终止 JBoss。 JBoss 连接到 H2 数据库并在其上创建锁,因此如果 JBoss 将立即被终止,那么数据库锁仍然存在。如果 JBoss 进程收到 CTRL+C,它会正确终止(删除数据库锁)。我想自动设置,在用户关闭 java 客户端应用程序后,JBoss 必须关闭,因为它收到 CTRL+C。 我不知道如何在 Windows 上执行此操作。但我是在 linux 上做的,我将我的代码添加到这个问题中。
抱歉,您的脚本毫无意义。 start call script2.bat
?? start
和 call
的组合是胡说八道。您使用其中之一,但不能同时使用两者。
此外,我不得不让你失望。无法关闭控制台,只能保留代码 运行。您甚至无法在 Windows 中启动隐藏控制台。关闭控制台将立即停止代码的执行。
编辑:
现在我明白你在问什么了。使用
开始你的第一个脚本start "somename" script1.bat
这将在控制台中以 "somename" 作为 window 标题启动 script1。
在第二个脚本中你可以使用这个:
:WORKING
REM Do some stuff here
REM and here
REM and here
FOR /f "tokens=*" %%A IN ('tasklist^ /v^| findstr /i /c:"somename"') DO GOTO WORKING
REM shutdown part
REM close db connections
REM exit script2
这部分将检查标题中带有 "somename" 的控制台是否为 运行,如果是,则重新进入循环。在循环结束时,它总是检查 script1 是否仍然处于活动状态。一旦找不到,代码就会继续到关闭部分。
如果你只想等待 script1 终止你可以使用 PING -n 5 127.0.0.1 > NUL
作为 5(或更长,只需替换 5 ^^)第二次超时以避免 busy-waiting:
:WORKING
PING -n 5 127.0.0.1 > NUL
FOR /f "tokens=*" %%A IN ('tasklist^ /v^| findstr /i /c:"somename"') DO GOTO WORKING
REM shutdown part
REM close db connections etc.
REM exit script2
如果在 JBoss 中启用了 CLI,那么 JBoss 可以通过 CLI 关闭。以下批处理显示如何关闭 JBoss
...
set environment variable
...
REM start jboss
start "UNIQUE_NAME" path_to_JBoss\bin\standalone.bat -c standalone.xml
REM start java application
java ...
REM shutdown JBoss by CLI
call path_to_JBoss\bin\jboss-cli.bat --connect ":shutdown"
REM it is just in case. If CLI did not shutdown JBoss, then following line kills JBoss without release of resource.
FOR /f "TOKENS=1,2,*" %%a IN ('tasklist^ /FI "WINDOWTITLE eq UNIQUE_NAME*" /nh') DO taskkill /pid %%b