为什么我重新启动的 Java 程序会失去键盘焦点?
Why does my restarted Java program lose keyboard focus?
我试图创建一个简化的故障保护 Java 应用程序,它会在被强制关闭时自行重启(在 Windows 中,使用 CTRL+C 的 CMD 命令)。
批处理代码如下所示:
@echo off
setlocal
start /wait java BatchWakeMeUpSomehow
if errorlevel 1 goto retry
echo Finished successfully
exit
:retry
echo retrying...
start /wait java BatchWakeMeUpSomehow
java 代码是这个:
public class WakeMeUpSomehow {
static class Message extends Thread {
public void run() {
try {
while(true)
{
System.out.println("Hello World from run");
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
public static void main(String[] args) {
try {
Runtime.getRuntime().addShutdownHook(new Message());
while(true)
{
System.out.println("Hello World");
Thread.sleep(100);
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
我想澄清一下我的理解。我认为因为 Java 运行s 在 JVM 环境中,所以它在重新启动强制关闭的 JVM 方面有一些限制(如果我们通过批处理文件重新启动强制关闭的 JVM,然后它失去了光标焦点,它只是 运行 在一个不能有键盘焦点的新 CMD window 中。
我的目标是让这个应用程序保持 运行 循环(la "digital wackamole" ),但我只能重新 运行 它一次(它是 运行在无响应的 CMD window )
有人建议我查看 Apache Daemon 工具,但我不确定这有什么帮助。
要在错误级别 1 及以上的情况下进行无限循环,请在 start
行之前添加标签:
:run
start /wait java BatchWakeMeUpSomehow
if errorlevel 1 echo retrying... & goto run
echo Finished successfully
但是这也会打开一个新的window,所以如果你想在已经启动的window中重新启动java
进程,你可以使用typeperf
来检查它的 CPU 用法(以便您可以强行关闭进程并重新启动它)或者在执行返回到批处理文件后重新启动 java
。
如果 java
进程退出(未挂起),我们可以用 tasklist
:
检测到它
:run
start java BatchWakeMeUpSomehow
:check
timeout 1 >nul
tasklist /fi "imagename eq java.exe" | find "java.exe" >nul
if errorlevel 1 echo retrying... & goto run
goto check
如果 java
进程挂起并且 CPU 使用率为 0% 1 分钟:
if not "%~1"=="childprocess" goto main
:loop
java BatchWakeMeUpSomehow
goto loop
:main
start "" "%~dpnx0" childprocess
:check
for /f "skip=2 delims=, tokens=2" %%a in ('
typeperf "\process(java)\%% processor time" -sc 1 -si 60
') do if %%a=="0.000000" taskkill /f /im java.exe
goto check
我试图创建一个简化的故障保护 Java 应用程序,它会在被强制关闭时自行重启(在 Windows 中,使用 CTRL+C 的 CMD 命令)。
批处理代码如下所示:
@echo off
setlocal
start /wait java BatchWakeMeUpSomehow
if errorlevel 1 goto retry
echo Finished successfully
exit
:retry
echo retrying...
start /wait java BatchWakeMeUpSomehow
java 代码是这个:
public class WakeMeUpSomehow {
static class Message extends Thread {
public void run() {
try {
while(true)
{
System.out.println("Hello World from run");
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
public static void main(String[] args) {
try {
Runtime.getRuntime().addShutdownHook(new Message());
while(true)
{
System.out.println("Hello World");
Thread.sleep(100);
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
我想澄清一下我的理解。我认为因为 Java 运行s 在 JVM 环境中,所以它在重新启动强制关闭的 JVM 方面有一些限制(如果我们通过批处理文件重新启动强制关闭的 JVM,然后它失去了光标焦点,它只是 运行 在一个不能有键盘焦点的新 CMD window 中。
我的目标是让这个应用程序保持 运行 循环(la "digital wackamole" ),但我只能重新 运行 它一次(它是 运行在无响应的 CMD window )
有人建议我查看 Apache Daemon 工具,但我不确定这有什么帮助。
要在错误级别 1 及以上的情况下进行无限循环,请在 start
行之前添加标签:
:run
start /wait java BatchWakeMeUpSomehow
if errorlevel 1 echo retrying... & goto run
echo Finished successfully
但是这也会打开一个新的window,所以如果你想在已经启动的window中重新启动java
进程,你可以使用typeperf
来检查它的 CPU 用法(以便您可以强行关闭进程并重新启动它)或者在执行返回到批处理文件后重新启动 java
。
如果
检测到它java
进程退出(未挂起),我们可以用tasklist
::run start java BatchWakeMeUpSomehow :check timeout 1 >nul tasklist /fi "imagename eq java.exe" | find "java.exe" >nul if errorlevel 1 echo retrying... & goto run goto check
如果
java
进程挂起并且 CPU 使用率为 0% 1 分钟:if not "%~1"=="childprocess" goto main :loop java BatchWakeMeUpSomehow goto loop :main start "" "%~dpnx0" childprocess :check for /f "skip=2 delims=, tokens=2" %%a in (' typeperf "\process(java)\%% processor time" -sc 1 -si 60 ') do if %%a=="0.000000" taskkill /f /im java.exe goto check