为什么我重新启动的 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