bat java 启动脚本_从bat脚本运行的Java应用程序上的Windows关闭挂钩
小編典典
在極少數(shù)情況下,虛擬機(jī)可能會中止,即在不完全關(guān)閉的情況下停止運(yùn)行。當(dāng)虛擬機(jī)在外部終止時(shí)會發(fā)生這種情況,例如在Unix上使用SIGKILL信號或在Microsoft
Windows上使用TerminateProcess調(diào)用。
因此,不幸的是,我認(rèn)為在這里無事可做。
Windows控制臺中的CTRL-
CLOSE信號。似乎不可調(diào)整。
引用以上鏈接:
CTRL+CLOSE當(dāng)用戶關(guān)閉控制臺時(shí),系統(tǒng)會生成信號。控制臺上連接的所有進(jìn)程均會接收信號,使每個(gè)進(jìn)程都有機(jī)會在終止之前進(jìn)行清理。當(dāng)進(jìn)程收到此信號時(shí),處理程序函數(shù)在執(zhí)行任何清除操作后可以采取以下操作之一:
調(diào)用ExitProcess以終止該過程。
返回FALSE。如果沒有注冊的處理程序函數(shù)返回TRUE,則默認(rèn)處理程序?qū)⒔K止該過程。
返回TRUE。在這種情況下,不會調(diào)用其他處理程序函數(shù),并且會彈出一個(gè)對話框詢問用戶是否終止該過程。如果用戶選擇不終止該過程,則系統(tǒng)將不會關(guān)閉控制臺,直到該過程最終終止。
UPD 。如果您可以接受本機(jī)調(diào)整,則WinAPI SetConsoleCtrlHandler函數(shù)將為您消除默認(rèn)行為打下基礎(chǔ)。
UPD2
。關(guān)于Java信號處理和終止的啟示是相對較老的文章,但是“
編寫Java信號處理程序” 部分可能確實(shí)包含您所需要的內(nèi)容。
UPD3 。我已經(jīng)嘗試了以上文章中的 Java信號處理程序
。它可以SIGINT很好地工作,但不是我們需要的,所以我決定隨身攜帶SetConsoleCtrlHandler。結(jié)果有點(diǎn)復(fù)雜,可能不值得在您的項(xiàng)目中實(shí)現(xiàn)。無論如何,它可以幫助其他人。
因此,想法是:
保留對關(guān)閉處理程序線程的引用。
使用JNI設(shè)置自定義本機(jī)控制臺處理程序例程。
在CTRL+CLOSE信號上調(diào)用自定義Java方法。
從該方法調(diào)用關(guān)閉處理程序。
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");
}
}
本機(jī)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代碼中,為清除起見,所有錯(cuò)誤檢查都被省略。關(guān)機(jī)處理程序?qū)?chuàng)建一個(gè)空文件"d:\shutdown.mark"來指示正確的關(guān)機(jī)。
所有的源代碼編譯的二進(jìn)制文件的測試在這里。
2020-09-21
總結(jié)
以上是生活随笔為你收集整理的bat java 启动脚本_从bat脚本运行的Java应用程序上的Windows关闭挂钩的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 加盟蛋糕店要多少钱啊?
- 下一篇: jmeter找不到java.dll_Wi