【问题标题】:How can I stop a DLL from terminating application servers when remote desktop sessions log off?当远程桌面会话注销时,如何阻止 DLL 终止应用程序服务器?
【发布时间】:2011-10-09 16:49:12
【问题描述】:

我有一个应用服务器(JBoss,但这也发生在 Tomcat 中)作为服务在 Windows Server 2003 中运行。它使用 -Xrs 标志运行。

在应用服务器下运行的 Java 应用程序通过 JNI 调用一个用 C++ 编写的可定制接口(意味着我们可以更改此代码),引用第三方 DLL 文件来处理图像(Lincoln 用于转换 PostScript)。

当我们通过远程桌面连接以控制台(mstsc /console)或管理员(mstsc /admin)模式登录服务器时,当我们注销时,如果林肯 DLL 文件已加载,应用程序服务器将确认注销发出信号,服务进程将立即终止,不影响。

我相信信号是CTRL_LOGOFF,但我可能不正确。

JavaJiggle Article on Signal Handling 之后,显然在处理 DLL 文件时将信号处理程序传递给 DLL 文件。这意味着第三方 DLL 文件(本例中为林肯)通过注销监听并响应 CTRL_LOGOFF 信号。

我相信,我应该能够在我的 C++ 接口中编写一个信号捕捉器到 DLL 以在 CTRL_LOGOFF 到达 DLL 之前拦截它,如果是这样,那么当有人注销时我们不会经常死掉控制台/管理员 RDP。

这是我需要的:

  1. 我是否更正了我在控制台/管理员注销/注销时收到的信号是 CTRL_LOGOFF

  2. 能否在C++接口中编写信号拦截器?

  3. 如何编码该信号拦截器,或者是否有预先存在的代码?我使用的是 32 位 DLL。

我找到了 Microsoft 文章 Registering a Control Handler Function,这可能有助于回答这个问题。

【问题讨论】:

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


    【解决方案1】:

    我似乎已经通过在每次调用第三方 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;
          }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2010-09-06
      • 1970-01-01
      • 1970-01-01
      • 2015-04-21
      • 2014-08-24
      • 2015-08-13
      • 2010-10-04
      • 2011-11-16
      相关资源
      最近更新 更多