Есть ли в любом случае, чтобы перехватить или убить всплывающее окно при вызове функции DLL через взаимодействие? - PullRequest
1 голос
/ 12 мая 2011

Я пишу приложение на C #, которое вызывает функцию внутри DLL, написанную с использованием неуправляемого кода.

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

У меня нет возможности узнать, произойдет ли это для данного вызова funciton или нет, и я бы не стал беспокоить пользователя этими окнами сообщений, так как иногда я вызываю эту функцию тысячи раз в пакетном процессе и Я бы предпочел, чтобы пользователю не приходилось нажимать «ОК», потому что там случается много сбоев.

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

Спасибо, Мистер М

Ответы [ 4 ]

2 голосов
/ 12 мая 2011

Исследуйте низкоуровневые вызовы Win API, они могут предложить решение для вас.

Например, использование Spy ++ может выявить имена окон, которые затем можно искать и закрывать.Затем, используя вызовы WINDOWS API ...

    using System.Runtime.InteropServices;

    // Get a handle to an application window.
    [DllImport("USER32.DLL", CharSet = CharSet.Unicode)]
    private static extern IntPtr FindWindow(string lpClassName,
        string lpWindowName);

    // Activate an application window.
    [DllImport("USER32.DLL")]
    private static extern bool SetForegroundWindow(IntPtr hWnd);

Затем в фоновом потоке напишите процесс, который ищет эти окна и закрывает их.

        //Some PsuedoCode, note loop should have a cancel condition!
        while (true)
        {
            //Get a handle.  
            handle = FindWindow(windowClassName,  windowName);

            //We found the window, close it
            if (handle != IntPtr.Zero)
            {
                //Send Close Command 
                SetForegroundWindow(handle);
                SendKeys.SendWait("%{F4}");
            }

            //Wait 200ms seconds before trying again
            System.Threading.Thread.Sleep(200);
        }

Возможно, вы сможетевыполните какое-нибудь хакерское решение, подобное этому, в своем приложении.

Обратите внимание, вам придется хранить windowClassName (s) и windowName (s) в каком-либо файле конфигурации или жестко кодировать их в своем приложении.

2 голосов
/ 12 мая 2011

Как вы подозреваете, вы не сможете подавить всплывающие окна из кода, который вы не написали, если только вызовы не имеют определенного параметра, который сделает это за вас.Связаны ли окна сообщений с определенными кодами ошибок?

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

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

1 голос
/ 12 мая 2011

Нет никакого способа предотвратить появление пользовательского интерфейса произвольной (неуправляемой) DLL, если она чувствует необходимость в этом.

Одной из неприятных решений является попытка закрыть окно сразу после его появления. То, как я бы это сделал, было бы

  • Начать другую тему. Его задача - записать текущее активное окно для процесса и закрыть все новые окна, которые появляются.
  • Сделайте вызов в DLL
  • Остановить нить

Это ни в коем случае не пуленепробиваемый процесс, но он может помочь вам обойти эту проблему.

0 голосов
/ 12 мая 2011

Было бы практично для вас запускать этот код из службы Windows?

Службам не разрешается показывать GUI (вы раньше имели возможность разрешить службе показывать GUI, ноMS постепенно сворачивает это).Я не знаю наверняка, но я думаю, что вызовы MessageBox () и тому подобное могут просто немедленно вернуться, когда вы вызываете их из неинтерактивного сервиса.

...