Обработка процесса конца приложения Windows

Не пробовал TypeScript. В JavaScript также следует рассмотреть возможность включения значений по умолчанию для свойств объекта, чтобы избежать ошибки

Uncaught TypeError: Cannot destructure property `arg1` of 'undefined' or 'null'.

для

sum()

const sum = ({ arg1, arg2, arg3 }) => 
  arg1 + arg2 + arg3;

try {
  console.log(sum())
} catch (e) {
  console.error(e)
}
[ 115]

, чего можно избежать, установив для каждого значения значение 0, где ожидаемые параметры и возвращаемое значение - это целое число JavaScript

[ 117]

const sum = ({ arg1 = 0, arg2 = 0, arg3 = 0 } = {}) => 
  arg1 + arg2 + arg3;

try {
  console.log(sum()) // 0
} catch (e) {
  console.error(e)
}

10
задан Rashmi Pandit 11 May 2009 в 07:11
поделиться

6 ответов

Нет, невозможно перехватить решение операционной системы о завершении процесса. Обратите внимание, что это не выполняется диспетчером задач, завершение процесса - это ответственность ядра.

Здесь вам нужно будет сделать две вещи:

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

Вот три ссылки на блог Рэймонда, объясняющие, почему вы не можете делать то, что просите.

10
ответ дан 3 December 2019 в 20:06
поделиться

Что вы можете сделать, так это получить идентификатор процесса и отслеживать процесс, а также использовать свойство HasExited, чтобы проверить, закончился ли процесс или нет. Ниже приведен быстрый код VB (извините, у меня сейчас нет VS. Это было написано мной на другом форуме)

Public Class Form1
    Dim p As ProcessStartInfo
    Dim process As Process
    Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
        p = New ProcessStartInfo("iexplore.exe")
        process = process.Start(p)
    End Sub

    Private Sub Button2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button2.Click
        MsgBox(process.Id)
        If process.HasExited Then
            MsgBox("yes")
        Else
            MsgBox("no")
        End If
    End Sub
End Class

Приведенный выше код запускает Internetexplorer, а кнопка проверяет, завершился ли процесс или нет. Вы можете использовать аналогичный процесс, чтобы получить все запущенные процессы и использовать идентификатор процесса.

1
ответ дан 3 December 2019 в 20:06
поделиться

How about a slightly different approach:

Have your application update a date time field e.g. LastPollDate every so often while it is running, and have a separate field e.g. "AppTerminatedNormally" which you set to N, and change to Y if you get a form close event.

If the app is killed via Task Manager, the date will not be updated any more, and your AppTerminatedNormally will still be no.

This way you could run a query that finds all rows where LastPollDate is older than 10 minutes and AppTerminatedNormally is N, and you would have all the sessions that were abnormally terminated.

3
ответ дан 3 December 2019 в 20:06
поделиться

Я не думаю, что это возможно сделать из приложения. Цель End Task - немедленно остановить процесс. Это не позволяет выполнить код очистки.

Шобан указал другой способ достижения вашей цели. Другое приложение или служба должны искать основной процесс. Когда другой процесс не может найти основной процесс, вы можете выполнить обработку базы данных на этом этапе.

1
ответ дан 3 December 2019 в 20:06
поделиться

Вы все собираетесь плюнуть на этот пост, но вот ...

Вы пытаетесь для решения проблемы на неправильном уровне (например, запуск кода в вашем приложении, когда ядро ​​убивает приложение). Настоящая проблема заключается в том, чтобы гарантировать, что база данных правильно отражает присутствие (или отсутствие) ее клиентских приложений.

Чтобы решить эту проблему, не позволяйте приложениям находиться в «неконгруэнтном состоянии» между взаимодействиями с пользователем. Другими словами, не запускайте транзакции, которые вы не можете быстро зафиксировать, не записывайте данные в файлы, которые оставляют файл в наполовину записанном или нечитаемом состоянии, и не храните ресурсы вне вашего приложения в неконгруэнтном состоянии. состояние вне взаимодействия с пользователем. Другими словами, если ваше приложение не t занят ответом на обработчик событий, он должен быть готов к немедленному закрытию.

Если вы будете следовать описанной выше практике, вы найдете очень мало сценариев, в которых вам нужно «быстро очистить» перед завершением. Вне взаимодействий, когда пользователь нажимает «ОК» или «Сохранить» и т. Д., Хорошо написанное приложение должно выдерживать немедленное завершение работы без какого-либо длительного повреждения или повреждения хранилищ данных.

Если вам абсолютно необходимо установить флаг в базе данных при выходе (что звучит типично для шаблона, используемого для определения, вошел ли пользователь в систему или нет), тогда рассмотрите любую из следующих альтернатив:

  1. Периодически (возможно, один раз каждые 30 секунд) вставлять / обновлять поле, подобное метке времени, в базе данных, чтобы указать, как давно приложение было в сети. Другие приложения могут проверять эти временные метки, чтобы определить, как давно другое приложение было в сети ... если значение находится в пределах последних 30 секунд, другое приложение все еще работает.

  2. Как справедливо предположил Вудхендж, создайте отдельный процесс (в идеале сервис ) для отслеживания статуса основного приложения. Службы Windows можно настроить на автоматический перезапуск в случае сбоя службы. Этот процесс мониторинга затем выдаст временные метки базе данных.

Обратите внимание, что оба приведенных выше предложения решают реальную проблему (обнаруживают, обращаются ли приложения к базе данных), не оставляя базу данных в «неконгруэнтном состоянии» (вышеупомянутый флаг установлен. «Y», когда приложение фактически не работает, и флаг должен быть «N»).

  • Как справедливо предположил Вудхендж, создайте отдельный процесс (в идеале - службу) для отслеживания статуса основного приложения. Службы Windows можно настроить на автоматический перезапуск в случае сбоя службы. Этот процесс мониторинга затем выдаст временные метки базе данных.

  • Обратите внимание, что оба приведенных выше предложения решают реальную проблему (обнаруживают, обращаются ли приложения к базе данных), не оставляя базу данных в «неконгруэнтном состоянии» (вышеупомянутый флаг установлен. «Y», когда приложение фактически не работает, и флаг должен быть «N»).

  • Как справедливо предположил Вудхендж, создайте отдельный процесс (в идеале - службу) для отслеживания статуса основного приложения. Службы Windows можно настроить на автоматический перезапуск в случае сбоя службы. Этот процесс мониторинга затем выдаст временные метки базе данных.

  • Обратите внимание, что оба приведенных выше предложения решают реальную проблему (обнаруживают, обращаются ли приложения к базе данных), не оставляя базу данных в «неконгруэнтном состоянии» (вышеупомянутый флаг установлен. «Y», когда приложение фактически не работает, и флаг должен быть «N»).

    2
    ответ дан 3 December 2019 в 20:06
    поделиться

    Если вы ориентируетесь на Windows Vista (или выше), вас может заинтересовать API RegisterApplicationRecoveryCallback ...

    http://msdn.microsoft.com/en-us/library /aa373345.aspx

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

    Вы можете p / вызвать этот API из C # (я сделал это), но имейте в виду, что когда ваш обратный вызов вызванное ваше приложение уже находится в очень плохом состоянии, и вы можете сделать очень мало предположений о состоянии вашей памяти. Если у вас есть какие-либо данные в памяти, которые вы хотите использовать в этой процедуре, я бы поместил их в статический объект в очень общей области видимости, чтобы у вас были наилучшие возможные шансы, что они не были «убраны».

    2
    ответ дан 3 December 2019 в 20:06
    поделиться
    Другие вопросы по тегам:

    Похожие вопросы: