Как вывести окно на передний план

Сценарий

На работе мне пришлось написать скрипт для копирования файла Excel, написанного в другой версии Excel, в то, что было установлено на моем компьютере, и отредактировать копию.

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

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

Поэтому мне нужен был способ автоматически вывести всплывающее окно Excel на передний план.

Первая попытка решения

Я посмотрел в Интернете и нашел код, который получает свойство MainWindowHandle процесса Excel, а затем использует его в качестве входных данных для функции Win32, чтобы вывести окно этого процесса на передний план:

MainWindowHandle — ложь

Этот код отлично работал для других окон, но по какой-то причине свойство System.Diagnostics.Process.MainWindowHandle имело значение 0 для всплывающего окна Excel, что означало, что функция SetForegroundWindow() не работала.

Я заметил, что свойство MainWindowHandle было > 0 для любого окна, у которого был значок на панели запуска Windows, поэтому, возможно, MainWindowHandle было равно 0, потому что, хотя всплывающее окно Excel имело графический интерфейс, на панели запуска не было значка.

Windows API может это сделать, так что я могу

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

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

Оказывается, Windows API не моделирует концепцию главного окна. Это полностью реализовано в среде .NET, которая применяет эвристику для определения того, что пользователь будет воспринимать как главное окно.

Рабочее решение

Благодаря IInspectable на StackOverflow.com, который направил меня к функции EnumWindows Win32, я смог написать код с правильным дескриптором :)

Теперь свойство MainWindowHandle › 0, мы можем вызвать функцию SetForegroundWindow():

Используя этот код, я теперь могу скопировать файл Excel, изменить его и автоматически вывести всплывающее окно Excel на передний план :D

Взгляните на мою страницу GitHub, чтобы увидеть весь код, который копирует файл Excel и редактирует его.

Весь код также показывает вам, как запустить код EnumWindows в своем собственном потоке, что вам необходимо сделать, поскольку это всплывающее окно Excel блокирует основной поток.