我有一个应用程序服务器(JBoss,但这也发生在 Tomcat 中)作为 Windows Server 2003 中的服务运行。它使用 -Xrs
标志运行。
在应用服务器下运行的 Java 应用程序通过 JNI 调用用 C++ 编写的可自定义接口(interface)(意味着我们可以更改此代码),引用第三方 DLL 文件来处理图像(Lincoln 用于转换 PostScript)。
当我们在控制台(mstsc/console
)或管理员(mstsc/admin
)模式下通过远程桌面连接登录服务器时,当我们注销时,如果Lincoln DLL文件加载完毕,应用服务器将确认注销信号,服务进程将立即终止,无任何影响。
我认为信号是 CTRL_LOGOFF
,但我可能错了。
在 JavaJiggle Article on Signal Handling 之后,显然信号处理程序在处理 DLL 文件时传递给 DLL 文件。这意味着第三方 DLL 文件(在本例中为 Lincoln)通过注销监听并响应 CTRL_LOGOFF
信号。
我相信,我应该能够在我的 DLL 的 C++ 接口(interface)中编写一个信号捕捉器,以在 CTRL_LOGOFF
到达 DLL 之前拦截它,如果是这样,那么我们就不会经常死有人注销控制台/管理员 RDP。
这是我需要的:
我在控制台/管理员注销/注销上收到的信号是
CTRL_LOGOFF
是否正确?我可以在 C++ 接口(interface)中编写信号拦截器吗?
如何编写信号拦截器的代码,或者是否有预先存在的代码?我正在使用 32 位 DLL。
我找到了 Microsoft 文章 Registering a Control Handler Function ,这可能有助于回答这个问题。
最佳答案
我似乎已经通过每次调用第三方 DLL 时向堆栈添加一个忽略处理程序来解决它,但我担心每次调用我的方法时,我们都会不断向堆栈添加处理程序,显然是第三方DLL 不会删除它的处理程序。我不知道这是否会造成内存泄漏。
有没有一种方法可以防止将第三方处理程序放在首位?我问了一个后续问题来回答这个问题: How can I prevent my Console Control Handler from being overridden? .
下面是我自定义的JNI类方法,调用了第三方DLL文件:
JNIEXPORT jint JNICALL Java_com_company_ConvertProxy_convertToImageType(JNIEnv *env, jclass cls, jstring input, jstring output) {
jboolean isCopy;
inFilename = env->GetStringUTFChars(input, &isCopy);
outFilename = env->GetStringUTFChars(output, &isCopy);
// I tried to call SetConsoleCtrlHandler() here, but failed;
// it turns out third-party code in ConvertImage() also
// calls SetConsoleCtrlHandler and overrides it if placed here.
int value = ConvertImage();
// Deafen Control Logoffs set by third-party ConvertImage.
// SetConsoleCtrlHandler( NULL, TRUE ); // DOES NOT WORK, must use custom CtrlHandler.
SetConsoleCtrlHandler( (PHANDLER_ROUTINE) CtrlHandler, TRUE );
return value;
}
BOOL CtrlHandler( DWORD fdwCtrlType ) {
switch( fdwCtrlType )
{
// Handle the CTRL-C signal.
case CTRL_C_EVENT:
return( TRUE );
// CTRL-CLOSE: confirm that the user wants to exit.
case CTRL_CLOSE_EVENT:
return( TRUE );
case CTRL_BREAK_EVENT:
return( TRUE );
case CTRL_LOGOFF_EVENT:
return( TRUE );
case CTRL_SHUTDOWN_EVENT:
return( TRUE );
default:
return FALSE;
}
}
关于c++ - 当远程桌面 session 注销时,如何阻止 DLL 终止应用程序服务器?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7704979/