如何使用GetForeGroundWindow()在C#中获取新启动的应用程序窗口句柄?

问题描述 投票:1回答:1

我试图使用C#中的P / Invoke使用GetForegroundWindow()捕获新启动的应用程序。但是,我得到的只是explorer.exe窗口句柄而不是已启动的实际进程窗口句柄(如notepad.exe或wordpad.exe)。

实际上,我想在用户打开“记事本”的同时记录用户输入的文本,同时我想得到“记事本”实例的实际句柄(如果打开了多个记事本实例)用户正在尝试写东西。

即我从Windows 7 Ultimate x64上的开始菜单启动notepad.exe,并运行基于C#.Net的应用程序按下按键。我在我的应用程序中设置了应用程序密钥挂钩,以便在文本更改事件时,应用程序尝试获取前台窗口。问题是:它获取explorer.exe而不是notepad.exe。

该代码适用于已经打开的窗口,但它不适用于任何应用程序的新启动实例,如chrome,记事本,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作为前景窗口读取。当我输入现有的打开的应用程序并且不启动应用程序的新实例时,相同的代码会读取正确的应用程序窗口。

我在某处读到有一些竞争条件问题。如果是这种情况,我该如何解决?

请帮我。我真的被困在这很久了。

谢谢。

c# process window pinvoke foreground
1个回答
1
投票

好。伙计们。问题不在于GetForegroundWindow()。也许这就是为什么我没有得到任何答案。我详细调试了这个问题并找到了问题所在。答案可以在这里找到纠正的代码。

Solution with Code

© www.soinside.com 2019 - 2024. All rights reserved.