c++ - 当远程桌面 session 注销时,如何阻止 DLL 终止应用程序服务器?

标签 c++ windows-services java-native-interface signals rdp

我有一个应用程序服务器(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。

这是我需要的:

  1. 我在控制台/管理员注销/注销上收到的信号是 CTRL_LOGOFF 是否正确?

  2. 我可以在 C++ 接口(interface)中编写信号拦截器吗?

  3. 如何编写信号拦截器的代码,或者是否有预先存在的代码?我正在使用 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/

相关文章:

c# - Entity Framework 6.1.3 : InvalidOperationException after a few days of running

java-native-interface - java JNI 错误 java.lang.UnsatisfiedLinkError :

java - jbyteArray 和 jbyte 指针的区别

java - 在 C (JNI) 中结束 Java 线程

linux - 有没有类似 Linux 的 Windows 终端服务?

c# - 事件日志写入权限

C++ - 如果循环内的语句无法正常工作

c++ - Vector 只获取无重复元素

c++ - 链接失败。如何使用 'NtQuerySystemTime' windows函数?

c++ - 在非数组指针上建立索引并读取最后一个元素之后的类型确定