Как я могу запретить DLL завершать работу серверов приложений при завершении сеансов удаленного рабочего стола?

У меня есть сервер приложений (JBoss, но это также происходит в Tomcat), работающий как служба в Windows Server 2003. Он работает с флагом -Xrs.

Приложение Java, работающее под управлением сервера приложений, вызывает настраиваемый интерфейс, написанный на C++ через JNI (это означает, что мы можем изменить этот код), ссылаясь на сторонний DLL-файл для обработки изображений (Lincoln для преобразования PostScript).

Когда мы входим на сервер через подключение к удаленному рабочему столу в режиме консоли (mstsc /console) или в режиме администратора (mstsc /admin), когда мы выходим из системы, если DLL-файл Lincoln загружен, сервер приложений подтвердит сигнал выхода из системы, и процесс службы немедленно прекратить без ущерба.

Я полагаю, что сигнал CTRL_LOGOFF, но могу ошибаться.

После статьи JavaJiggle об обработке сигналов, очевидно, обработчики сигналов передаются в DLL-файл при обработке DLL-файла. Это означает, что сторонний файл DLL (в данном случае Линкольн) прослушивает сигнал CTRL_LOGOFF и отвечает на него выходом из системы.

Я считаю, что я должен быть в состоянии закодировать улавливатель сигналов в моем интерфейсе C++ для DLL, чтобы перехватывать CTRL_LOGOFF до того, как он достигнет DLL, и если это так, то мы не будем постоянно умирать, когда кто-то выходит из консоли/администратора RDP.

Вот что мне нужно:

  1. Правильно ли я понимаю, что сигнал, который я получаю при выходе из консоли/администратора/выходе из системы, равен CTRL_LOGOFF?

  2. Могу ли я написать перехватчик сигналов в интерфейсе C++?

  3. Как мне закодировать этот перехватчик сигнала, или есть уже существующий код? Я использую 32-битную DLL.

Я нашел статью Microsoft Регистрация функции обработчика элементов управления, которая может помочь ответить на этот вопрос.


person JoshDM    schedule 09.10.2011    source источник


Ответы (1)


Кажется, я решил эту проблему, добавляя обработчик игнорирования в стек каждый раз, когда вызывается сторонняя DLL, но я боюсь, что каждый раз, когда я вызываю свой метод, мы продолжаем добавлять обработчики в стек, и, очевидно, сторонняя DLL этого не делает. удалить его обработчики. Я не знаю, создает ли это утечку памяти.

Есть ли способ предотвратить размещение стороннего обработчика? Я задал дополнительный вопрос, чтобы ответить на это: Как я могу предотвратить переопределение моего обработчика управления консолью?.

Вот мой пользовательский метод класса 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;
      }
}
person JoshDM    schedule 12.10.2011