Какое самое последнее место, где вы можете выполнять логику в исполняемом файле Windows? - PullRequest
4 голосов
/ 17 августа 2010

В моем приложении я хочу выполнить логику в самый последний момент. Чем позже, тем лучше.

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

До сих пор мы делали это, используя несколько уловок.

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

Второй трюк состоял в том, чтобы определить глобальную переменную следующим образом:

#pragma init_seg(lib)
GlobalApplicationManager s_globalApplicationManager;

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

Проблема в том, что, начиная с Windows 7, деструктор больше не вызывается в некоторых ситуациях. На данный момент неясно, что на это влияет, но мы уверены, что он не вызывается, если мы установим успешное соединение с Oracle в нашем приложении.

Какие еще хитрости существуют для выполнения кода как можно позже в приложении?

Ответы [ 5 ]

7 голосов
/ 17 августа 2010

Используйте /ENTRYPOINT. В пользовательской точке входа вызовите точку входа CRT, а затем свою окончательную логику.

2 голосов
/ 17 августа 2010

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

для глобальных переменных вы можете определить функцию уничтожения void func() и вызвать atexit(func) при инициализации.

1 голос
/ 18 августа 2010

Вы можете поместить свою логику в функцию DllMain(DLL_PROCESS_DETACH) во вспомогательной DLL. Это происходит даже после того, как точка входа в EXE вернулась (при условии, что даже возвращается - это может не произойти из-за TerminateThread), поэтому она более надежна и позже, чем раннее предложение Бена Фойгта.

Не думайте, что вы можете сделать слишком много. Это в значительной степени самое последнее место, где вы можете выполнять логику, но вы не можете больше полагаться на присутствие других DLL. Вот и весь смысл DLL_PROCESS_DETACH. Вы можете рассчитывать только на то, что Kernel32.DLL останется.

1 голос
/ 17 августа 2010

Существует определенное CRT количество разделов, к которым вы можете добавлять свои собственные вызовы с помощью #pragma.Используя правильное имя, вы можете добавить код в различные моменты процесса инициализации и завершения работы.Однако найти имена нелегко.

Для некоторых имен посмотрите "crt0dat.c" в источнике CRT, установленном вместе с VS2010.

0 голосов
/ 17 августа 2010

Почему бы просто не передать вашему окну / приложению собственное сообщение после вызова ShowWindow?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...