On 2020-05-06 11:09, Julius Bullinger wrote:
Usually, sending a WM_QUIT message to a QApplication triggers the QCoreApplication::aboutToQuit() signal, e.g. when ending the application via Windows's Task Manager, or using "taskkill /PID <pid>".

We discovered that no aboutToQuit() signal is emitted when a QApplication without windows receives a WM_QUIT:

    #include <QApplication>
    #include <QDebug>
    #include <QWidget>

    int main(int argc, char *argv[]) {
      QApplication app(argc, argv);

      QApplication::connect(&app, &QApplication::aboutToQuit, []() {
        qDebug() << "QApplication::aboutToQuit";
      });

      // Commenting those lines will not trigger aboutToQuit() when
      // the application is closed via Task Manager:
      QWidget w;
      w.show();

      return app.exec();
    }

Our application supports a text-only variant, where the GUI is disabled. We're basically doing it like that, and wondered why our shutdown code was not called when the application was quit via the Task Manager.

Is there anything that needs to be done to get consistent behavior?

Hi, when running apps on Windows without a window, you'll be missing out on a lot of inter-process stuff like WM_QUIT (that's why it's common for windowless apps to create a hidden, non-interactive window just to be able to receive all those WM_XXX). So no aboutToQuit() will be emitted for you when you skip creating that widget window.

But there's an API for windowless apps where you can receive a control signal, e.g. Ctrl-C was pressed or someone (like the Task Manager) is shutting down the app, more here: https://docs.microsoft.com/en-us/windows/console/setconsolectrlhandler and the callback: https://docs.microsoft.com/en-us/windows/console/handlerroutine

There's no support for that API in Qt but it's pretty easy to use. Here's an example, I created a vanilla Qt console app, and changed main.cpp to this:
-----------------------------------------
#include <QCoreApplication>
#include <windows.h>

BOOL WINAPI CtrlHandler(DWORD fdwCtrlType)
{
    switch (fdwCtrlType)
    {
    case CTRL_CLOSE_EVENT:
         ::OutputDebugStringA("Ctrl-Close event"); // catch taskkill or Task Manager End task
        return TRUE;

    default:
        return FALSE;
    }
}

int main(int argc, char *argv[])
{
    QCoreApplication app(argc, argv);

    SetConsoleCtrlHandler(CtrlHandler, TRUE);

    return app.exec();
}
-----------------------------------------
Note: I'm using OutputDebugString and DbgView.exe to view the output, qDebug() output has a tendency to disappear when you test with "End task" from TaskManager.

Note 2: this API is very flakey if you try it from a GUI-built .exe, for Qt apps I mean built with "QT += core gui etc" in the .pro file, and use of QApplication in main.cpp. Instead you need to build your app like a Qt console app, "QT -= gui" and CONFIG += console, and use QCoreApplication in main.cpp, like in my example above.

Rgrds Henry

_______________________________________________
Interest mailing list
Interest@qt-project.org
https://lists.qt-project.org/listinfo/interest

Reply via email to