栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 面试经验 > 面试问答

从bat脚本运行的Java应用程序上的Windows关闭挂钩

面试问答 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

从bat脚本运行的Java应用程序上的Windows关闭挂钩

从addShutdownHook文档中:

在极少数情况下,虚拟机可能会中止,即在不完全关闭的情况下停止运行。当虚拟机在外部终止时会发生这种情况,例如在Unix上使用SIGKILL信号或在Microsoft
Windows上使用TerminateProcess调用。

因此,不幸的是,我认为在这里无事可做。


Windows控制台中的CTRL-
CLOSE
信号。似乎不可调整。

引用以上链接:

CTRL+CLOSE
当用户关闭控制台时,系统会生成信号。控制台上连接的所有进程均会接收信号,使每个进程都有机会在终止之前进行清理。当进程收到此信号时,处理程序函数在执行任何清除操作后可以采取以下操作之一:

  • 调用
    ExitProcess
    以终止该过程。
  • 返回
    FALSE
    。如果没有注册的处理程序函数返回
    TRUE
    ,则默认处理程序将终止该过程。
  • 返回
    TRUE
    。在这种情况下,不会调用其他处理程序函数,并且会弹出一个对话框询问用户是否终止该过程。如果用户选择不终止该过程,则系统将不会关闭控制台,直到该过程最终终止。

UPD 。如果您可以接受本机调整,则WinAPI

SetConsoleCtrlHandler
函数将为您消除默认行为打下基础。

UPD2
。关于Java信号处理和终止的启示是相对较老的文章,但是“
编写Java信号处理程序” 部分可能确实包含您所需要的内容。


UPD3 。我已经尝试了以上文章中的 Java信号处理程序
。它可以

SIGINT
很好地工作,但不是我们需要的,所以我决定随身携带
SetConsoleCtrlHandler
。结果有点复杂,可能不值得在您的项目中实现。无论如何,它可以帮助其他人。

因此,想法是:

  1. 保留对关闭处理程序线程的引用。
  2. 使用JNI设置自定义本机控制台处理程序例程。
  3. CTRL+CLOSE
    信号上调用自定义Java方法。
  4. 从该方法调用关闭处理程序。

Java代码:

public class TestConsoleHandler {    private static Thread hook;    public static void main(String[] args) {        System.out.println("Start");        hook = new ShutdownHook();        Runtime.getRuntime().addShutdownHook(hook);        replaceConsoleHandler(); // actually not "replace" but "add"        try { Thread.sleep(10000); // You have 10 seconds to close console        } catch (InterruptedException e) {}    }    public static void shutdown() {        hook.run();    }    private static native void replaceConsoleHandler();    static {        System.loadLibrary("TestConsoleHandler");    }}class ShutdownHook extends Thread {    public void run() {        try { // do some visible work new File("d:/shutdown.mark").createNewFile();        } catch (IOException e) { e.printStackTrace();        }        System.out.println("Shutdown");    }}

本机

replaceConsoleHandler

JNIEXPORT void JNICALL Java_TestConsoleHandler_replaceConsoleHandler(JNIEnv *env, jclass clazz) {    env->GetJavaVM(&jvm);    SetConsoleCtrlHandler(&HandlerRoutine, TRUE);}

和处理程序本身:

BOOL WINAPI HandlerRoutine(__in DWORD dwCtrlType) {    if (dwCtrlType == CTRL_CLOSE_EVENT) {        JNIEnv *env;        jint res =  jvm->AttachCurrentThread((void **)(&env), &env);        jclass cls = env->FindClass("TestConsoleHandler");        jmethodID mid = env->GetStaticMethodID(cls, "shutdown", "()V");        env->CallStaticVoidMethod(cls, mid);        jvm->DetachCurrentThread();        return TRUE;    }    return FALSE;}

而且有效。在JNI代码中,为清除起见,所有错误检查都被省略。关机处理程序将创建一个空文件

"d:shutdown.mark"
来指示正确的关机。

所有的源代码编译的二进制文件的测试在这里。



转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/495656.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号