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

小编典典

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

Windows上使用TerminateProcess调用。

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

Windows控制台中的CTRL-

CLOSE信号。似乎不可调整。

引用以上链接:

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

调用ExitProcess以终止该过程。

返回FALSE。如果没有注册的处理程序函数返回TRUE,则默认处理程序将终止该过程。

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

UPD 。如果您可以接受本机调整,则WinAPI SetConsoleCtrlHandler函数将为您消除默认行为打下基础。

UPD2

。关于Java信号处理和终止的启示是相对较老的文章,但是“

编写Java信号处理程序” 部分可能确实包含您所需要的内容。

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

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

因此,想法是:

保留对关闭处理程序线程的引用。

使用JNI设置自定义本机控制台处理程序例程。

在CTRL+CLOSE信号上调用自定义Java方法。

从该方法调用关闭处理程序。

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"来指示正确的关机。

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

2020-09-21

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值