Как я могу остановить DLL от завершения серверов приложений, когда сеансы удаленного рабочего стола выходят из системы? - PullRequest
1 голос
/ 09 октября 2011

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

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

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

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

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

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

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

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

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

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

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

1 Ответ

0 голосов
/ 13 октября 2011

Кажется, я решил эту проблему, добавляя обработчик игнорирования в стек каждый раз, когда вызывается сторонняя 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;
      }
}
...