为什么我重新启动的Java程序失去了键盘焦点



我尝试创建一个简化的failsafe 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在JVM环境中运行,所以它在重新启动被强制关闭的JVM方面有一些限制(如果我们通过批处理文件重新启动强制关闭的JVM,那么它就会失去光标焦点,它只是在一个不能有键盘焦点的新CMD窗口中运行。

我的目标是让这个应用程序保持在一个循环中运行(一个la"digital wackamole"),但我只能重新运行一次(它在一个无响应的CMD窗口中运行)

有人建议我看看Apache Daemon工具,但我不确定这有什么帮助。

要在errorlevel 1及以上的情况下进行无限循环,在start行之前添加一个标签:

:run
start /wait java BatchWakeMeUpSomehow
if errorlevel 1 echo retrying... & goto run
echo Finished successfully

然而,这也会打开一个新窗口,所以如果你想在已经启动的窗口中重新启动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
    

相关内容

最新更新