Закрытие MessageBox автоматически - PullRequest
1 голос
/ 16 сентября 2010

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

Теперь проблема в том, что программа может использоваться с автоматизацией. Если MessageBox создается во время автоматизации, он навсегда блокирует процесс, потому что никто не нажимает кнопку «ОК».

Кто-нибудь знает, как перехватить это окно с сообщением и автоматически закрыть его?

Все, что является честной игрой, пока это не то, что разозлит наборы безопасности. Это означает отсутствие перехвата или туннелирования кода.

Итак, мне нужно отловить при создании MessageBox и закрыть его. Создание MessageBox находится вне моего контроля. Изменение кода во время выполнения недопустимо.

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

РЕДАКТИРОВАТЬ: Дополнительное примечание, я могу найти окно сообщения через поиск во всех окнах, пока не найду окно с соответствующим названием, а затем отправлю ему сообщение WM_CLOSE, но я не думаю, что это хорошее решение. У меня также нет гарантии, что окно сообщения было / будет отображаться, или как долго после моего звонка оно будет отображаться. Он может отображаться мгновенно, спустя 1200 мс или вообще не отображаться.

Ответы [ 5 ]

4 голосов
/ 16 сентября 2010

Непосредственно перед тем, как вы начнете процесс шифрования, установите WH_CBT hook и в его callback найдите nCode HCBT_CREATEWND. Если вы получаете соответствующее имя класса ('# 32770 (Dialog)'?) И соответствующий заголовок, либо возвращаете ненулевое значение из обратного вызова, либо если это не работает, отправьте WM_CLOSE (или BM_CLICK в соответствующая кнопка, если необходимо выбрать опцию). Удалите ловушку после процесса, чтобы не связываться со всеми возможными диалоговыми окнами, всплывающими в вашем приложении.

3 голосов
/ 16 сентября 2010

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

Возможно, в этой библиотеке есть какая-либо конфигурация или настройка, которая может отключить использование сообщенияящики?

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

1 голос
/ 16 сентября 2010

Можно надеяться, что он будет найден GetForegroundWindow, но это может поймать другие приложения. Более грубый способ - перебирать все окна с помощью EnumWindows в поисках чего-либо с заголовком или текстом, равным указанному в библиотеке.

0 голосов
/ 23 сентября 2010

Создать новую тему. Если ваша функция завершается сбоем и открывается окно сообщения, получите дескриптор окна сообщения, пройдя по окнам (GetTopWindow, GetNextWindow) и сравнив идентификатор процесса окна с идентификатором, возвращенным из GetCurrentProcessId().

Или, вы можете избежать всей тяжелой работы и просто подключить MessageBox API к обходным путям. Это не очень сложно, и если вы не хотите платить за объезд, вы можете сделать это вручную.

  1. Вызвать VirtualProtect и установить защиту памяти в MessageBox на PAGE_EXECUTE_READWRITE
  2. Создайте голую функцию и используйте ее как батут.
  3. Создайте функцию, идентичную по параметрам MessageBox (это будет ваша ловушка)
  4. Создайте переход из MessageBox к вашей функции подключения.
0 голосов
/ 16 сентября 2010

Я однажды "дистанционно управлял" приложением, отправляя события щелчка мышью некоторым элементам управления Я предполагаю, что вам придется сделать это в отдельном потоке, который отслеживает события, если окно открыто. Довольно некрасиво, но работает ...

...