Как использовать GetForeGroundWindow (), чтобы получить вновь запущенный дескриптор окна приложения в C #? - PullRequest
1 голос
/ 01 апреля 2012

Я пытаюсь перехватить вновь запущенное приложение, используя GetForegroundWindow () , используя P / Invoke в C #.Однако все, что я получаю, это дескриптор окна explorer.exe вместо фактического дескриптора окна процесса (такого как notepad.exe или wordpad.exe), который был запущен.

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

т.е. я запускаю notepad.exe из меню «Пуск» в Windows 7 Ultimate x64 с моим приложением на C # .Net, работающим для нажатых клавиш.В моем приложении настроены перехватчики ключей приложения, так что при изменении текста текст приложение пытается получить окно переднего плана.Проблема заключается в следующем: он получает файл explorer.exe вместо notepad.exe.

Код отлично работает для уже открытых окон, но не работает для вновь запущенных экземпляров любого приложения, например Chrome, Notepad, WordPad.или любой другой.Вместо того, чтобы записывать текст в нужное приложение, он записывает текст для explorer.exe.Вот мой код:

    private string GetActiveWindowTitle()
    {
        const int nChars = 256;
        IntPtr handle = IntPtr.Zero;
        StringBuilder Buff = new StringBuilder(nChars);
        handle = GetForegroundWindow();

        if (GetWindowText(handle, Buff, nChars) > 0)
        {
            return Buff.ToString();
        }
        return null;
    }
    Process GetActiveProcess()
    {
        Process[] AllProcess = Process.GetProcesses();
        String title = GetActiveWindowTitle();

        foreach (Process pro in AllProcess)
        {
            if (title.Equals(pro.MainWindowTitle))
            {
                return pro;
            }
        }
        return Process.GetCurrentProcess();
    }

    string GetActiveProcessFileName()
    {
        IntPtr hwnd = GetForegroundWindow();
        SetForegroundWindow(hwnd);
        uint pid;
        GetWindowThreadProcessId(hwnd, out pid);
        Process p = Process.GetProcessById((int)pid);
        //p.MainModule.FileName.Dump();
        return p.ProcessName;
    }

    ProcessInfo GetActiveProcessInfo()
    {
        IntPtr hwnd = GetForegroundWindow();

        const int nChars = 256;
        StringBuilder Buff = new StringBuilder(nChars);
        uint pid;
        GetWindowThreadProcessId(hwnd, out pid);
        Process p = Process.GetProcessById((int)pid);
        ProcessInfo pi = new ProcessInfo();
        if (GetWindowText(hwnd, Buff, nChars) > 0)
        {
            pi.ProcessTitle = Buff.ToString();
        }
        pi.ProcessName = p.ProcessName;
        pi.ProcessHandle = (int)p.MainWindowHandle;

        return pi;
    }

GetActiveProcessInfo возвращает файл explorer.exe вместо правильного приложения, т.е. notepad.exe, потому что GetForegroundWindow () считывает explorer.exe в качестве окна переднего плана.Тот же код читает правильное окно приложения, когда я печатаю в существующих открытых приложениях и не запускаю новый экземпляр приложения.

Я где-то читал, что существует какая-то проблема состояния гонки.если это так, как я могу решить это?

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

Спасибо.

1 Ответ

1 голос
/ 14 апреля 2012

Хорошо.Ребята.Проблема была не с GetForegroundWindow ().Может быть, поэтому я не получил никакого ответа на это.Я отладил проблему подробно и нашел проблему.Ответ можно найти здесь с исправленным кодом.

Решение с кодом

...