关于Java应用程序运行Windows关机钩从蝙蝠脚本 [英] Windows shutdown hook on java application run from a bat script
问题描述
我有它运行的Java应用程序蝙蝠脚本。如果我美元是p $ PSS CTRL + C,它的应用程序终止摆好,调用全部关闭挂钩。不过,如果我只是关闭蝙蝠脚本的cmd窗口,关机钩永远不会调用。
I have a bat script which runs a java application. If I press ctrl+c on it, it the application terminates gracefully, invoking all the shutdown hooks. However, if I just close the cmd window of the bat script, the shutdown hooks are never invoked.
有没有办法解决这个问题的方法吗?或许有一种方法来告诉蝙蝠脚本时如何关闭其窗口终止调用的应用程序?
Is there a way to solve this? Perhaps there's a way to tell the bat script how to terminate the invoked applications when its window is closed?
推荐答案
从<一个href=\"http://docs.oracle.com/javase/7/docs/api/java/lang/Runtime.html#addShutdownHook%28java.lang.Thread%29\">addShutdownHook文档:
在罕见的情况下,虚拟机可能会中止,也就是停止工作,没有干净关闭运行。当虚拟机被外部终止,例如用在Unix上SIGKILL信号或者在Microsoft Windows TerminateProcess调用发生这种情况。
In rare circumstances the virtual machine may abort, that is, stop running without shutting down cleanly. This occurs when the virtual machine is terminated externally, for example with the SIGKILL signal on Unix or the TerminateProcess call on Microsoft Windows.
因此,我认为没有什么在这里做,很遗憾。
So i think nothing to do here, unfortunately.
<一个href=\"http://msdn.microsoft.com/en-us/library/windows/desktop/ms682535%28v=vs.85%29.aspx\">CTRL-CLOSE信号在Windows控制台。似乎非可修改
CTRL-CLOSE signal in Windows Console. Seems non-tweakable.
引用上面的链接:
该系统在用户关闭控制台生成一个 CTRL + CLOSE
信号。附连到控制台的所有进程接收该信号,给每个过程的机会终止之前进行清理。当一个进程接收到这个信号,处理函数可以采取以下措施之一进行任何清理操作后:
The system generates a
CTRL+CLOSE
signal when the user closes a console. All processes attached to the console receive the signal, giving each process an opportunity to clean up before termination. When a process receives this signal, the handler function can take one of the following actions after performing any cleanup operations:
- 呼叫
了ExitProcess
终止进程。 - 返回
FALSE
。如果没有注册的处理函数返回的TRUE
,默认的处理程序将终止进程。 - 返回
TRUE
。在这种情况下,没有其它的处理功能被调用,并且弹出对话框询问用户是否要终止进程。如果用户选择不终止的过程中,该系统不关闭控制台直到过程最后终止。
- Call
ExitProcess
to terminate the process. - Return
FALSE
. If none of the registered handler functions returnsTRUE
, the default handler terminates the process. - Return
TRUE
. In this case, no other handler functions are called, and a pop-up dialog box asks the user whether to terminate the process. If the user chooses not to terminate the process, the system does not close the console until the process finally terminates. - 请参考停机处理线程。
- 设置自定义的本机控制台处理程序用JNI程序。
- 在
CTRL + CLOSE
信号调用自定义的Java方法。 - 呼叫停机处理。
- Keep reference to shutdown handler thread.
- Set custom native console handler routine with JNI.
- Call custom Java method on
CTRL+CLOSE
signal. - Call shutdown handler from that method.
UPD 。如果原来的调整是给你接受,WinAPI的 SetConsoleCtrlHandler
函数打开的默认行为燮pressing方式。
UPD. If native tweaks are acceptable for you, WinAPI SetConsoleCtrlHandler
function opens way for suppressing of default behavior.
UPD2 。关于Java的信号处理和终止相对较老的文章,但部分的编写Java信号启示处理器的真可能包含你所需要的。
UPD2. Revelations on Java signal handling and termination relatively old article, but section Writing Java signal handlers really may contain what you need.
UPD3 。
我从文章试过的 Java的信号处理程序的上方。它与 SIGINT
好听,但它不是我们所需要的,我决定与 SetConsoleCtrlHandler
来实现它。结果是有点复杂,可能是不值得在项目实施。无论如何,它可以帮助别人。
UPD3.
I've tried Java signal handlers from article above. It works with SIGINT
nicely, but it not what we need, and i decided to carry it with SetConsoleCtrlHandler
. The result is a bit complicated and may be not worth to implement in your project. Anyway, it could help someone else.
所以,当时的想法是:
从该方法
Java的code:
Java code:
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 code所有的错误检查省略了间隙。关闭处理程序创建空文件D:\\ shutdown.mark。
指明正确停机时
And it works. In JNI code all error checks are omitted for clearance. Shutdown handler creates empty file "d:\shutdown.mark"
to indicate correct shutdown.
在这里编译的二进制文件的测试完整的来源。
Complete sources with compiled test binaries here.
这篇关于关于Java应用程序运行Windows关机钩从蝙蝠脚本的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!