Я создаю управляемый интерфейс пользовательского интерфейса WPF для устаревшего Win32-приложения. Внешний интерфейс WPF - это исполняемый файл; как часть его процедур запуска, я запускаю старое приложение как DLL во втором потоке. Любая UI-операция (включая CreateWindowsEx
и т. Д.) Унаследованного приложения вызывается обратно в основной поток UI.
Как часть процесса закрытия приложения, я хочу, чтобы очистить должным образом. Помимо прочего, я хочу вызвать DestroyWindow
на всех неуправляемых окнах, чтобы они могли должным образом очистить себя. Таким образом, во время выключения я использую EnumWindows
, чтобы попытаться найти все мои неуправляемые окна. Затем я вызываю DestroyWindow один список, который я генерирую. Они запускаются в основном UI-потоке.
После этого базового знания перейдем к моему актуальному вопросу:
В процедуре перечисления EnumWindows я должен проверить, является ли одно из возвращенных окон верхнего уровня одним из моих неуправляемых окон. Я делаю это, вызывая GetWindowThreadProcessId
, чтобы получить идентификатор процесса и идентификатор потока создателя окна. Я могу сравнить идентификатор процесса с Process.GetCurrentProcess().Id
, чтобы проверить, создало ли это мое приложение.
Для дополнительной безопасности я также хочу посмотреть, создавал ли мой основной поток пользовательского интерфейса окно. Однако возвращенный идентификатор потока является идентификатором потока ОС (который отличается от идентификатора управляемого потока). Как объяснено в этом вопросе , CLR оставляет за собой право перепланировать управляемый поток на другие потоки ОС. Могу ли я рассчитывать на то, что CLR будет «достаточно умным», чтобы никогда не делать этого для основного потока пользовательского интерфейса (из-за привязки потока к пользовательскому интерфейсу)? Затем я мог бы позвонить GetCurrentThreadId
, чтобы получить идентификатор неуправляемого потока основного пользовательского интерфейса для сравнения.