Приложение неожиданно закрылось из-за сообщений WM_CLOSE - PullRequest
2 голосов
/ 27 января 2020

У меня есть приложение MF C Dialog, которое запускается в области уведомлений (на панели задач). Иногда он просто отключается без всякой рифмы или причины.

После многих лет борьбы с этим, думая, что это повреждение памяти или что-то в этом роде, я добавил некоторые записи.

Оказывается, я получаю WM_CLOSE сообщения откуда-то. Но я не знаю где. У меня есть собственный код принудительного выключения для обновлений и тому подобное, но они хорошо зарегистрированы и никогда не запускаются.

Интересно то, что мое приложение должно выполнить небольшую очистку, чтобы убедиться, что не в середине операции с базой данных. Поэтому внутри OnClose () я на самом деле не закрываюсь сразу, а устанавливаю флаг, и в следующий раз, когда мой таймер задач срабатывает, если вызывается OnClose (), он вызывается снова, чтобы действительно завершить работу приложения.

Итак, в журналах я вижу полдюжины быстрых последовательных вызовов OnClose (), а затем программа просто исчезает. Он никогда не вызывает мою фактическую пост-очистку OnClose (), потому что мой таймер работает с интервалом в 5 секунд, поэтому моя очистка начинается, но мое отключение никогда не вызывается.

Я не могу не думать, что эти вызовы поступают от внешнего процесс - Windows обновление или что-то - и иногда системные журналы событий Windows указывают на обновление безопасности или gupdate.exe, запускаемое примерно в это время. Но компьютер даже не перезагружается. Похоже, что-то посылает мне полдюжины сообщений Close, а затем убивает программу.

Я думаю, что схожу с ума - действительно ли какой-то внешний процесс действительно закрывает мое приложение? Или я здесь совершенно не на том пути?

Может быть, я не следую передовым методам, но борюсь с этим. Это приложение должно быть запущено (огромная попытка перейти на обслуживание, кстати) 24/7, но я продолжаю получать эти неожиданные исчезновения.

(Правка) По запросу я добавил код OnClose () здесь , В первый раз (в другом) я установил флаг, указывающий, что мы ожидаем закрытия. Когда таймер запускается в следующий раз, он видит этот флаг, устанавливает CloseNow и вызывает OnClose ()

Когда возникает такая ситуация, я вижу несколько сообщений «в ожидании закрытия» в журнале, но он никогда не попадает в состояние CloseNow для закрытия вниз правильно. Но приложение закрывается.

В моем коде нет ничего, что отправляло бы несколько сообщений OnClose. Сначала я думал, что это может быть функция processmessages (), но она туда даже не доходит.

void CBPTillBotDlg::OnClose()  {

// Got a close message, tell timer we're shutting down.
m_iKillingApplication = true;
InstallIcon(NIM_MODIFY,MODE_IDLE);


// if the timer has returned and says it is okay to close now
if (m_iCloseNow) {

    // On a normal close when the timer sets m_iCloseNow
    // we fall into here and cleanup.
    // *** With the OnClose() problem, this code never gets hit.

    BECLog lLog;

    lLog.WriteString("CBPTillBotDlg::OnClose() Stopping Timer");

    m_btTimer->StopTimer();

    lLog.WriteString("CBPTillBotDlg::OnClose() Calling Getfields()");

    GetFields(); 

    lLog.WriteString("CBPTillBotDlg::OnClose() Kill Tabs");
    if (m_pdImport!=NULL) {
        m_pdImport->DestroyWindow();
        delete m_pdImport;
        m_pdImport = NULL;
    }
    if (m_pdExport!=NULL) {
        m_pdExport->DestroyWindow();
        delete m_pdExport;
        m_pdExport = NULL;
    }
    if (m_pdBackup!=NULL) {
        m_pdBackup->DestroyWindow();
        delete m_pdBackup;
        m_pdBackup = NULL;
    }
    if (m_pdError!=NULL) {
        m_pdError->DestroyWindow();
        delete m_pdError;
        m_pdError = NULL;
    }
    if (m_pdReport!=NULL) {
        m_pdReport->DestroyWindow();
        delete m_pdReport;
        m_pdReport = NULL;
    }

    lLog.WriteString("CBPTillBotDlg::OnClose() Save Config");
    m_tbCfg->Save(); 

    lLog.WriteString("CBPTillBotDlg::OnClose() Delete Literals");
    if (m_pLiteral!=NULL) {
        delete (m_pLiteral);
        m_pLiteral = NULL;
    }

    lLog.WriteString("CBPTillBotDlg::OnClose() Shut Down Normally");

    ProcessMessages();
    Sleep(0);
    CDialog::OnClose();
}
else {
    // First time WM_CLOSE
    // Set WaitToClose to indicate that we're closing.
    // The next time the timer fires (which means we're done current processing) the timer knows to set m_iCloseNow
    // *** With OnClose() problem, we're coming in here multiple times and not from any of our code. 
    m_bWaitToClose = TRUE;

    BECLog lLog;
    lLog.WriteString("CBPTillBotDlg::OnClose() Bot Waiting to Close");
}

}

...