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

如何使用GetForeGroundWindow()在C#中获取新启动的应用程序窗口句柄?,c#,process,window,pinvoke,foreground,C#,Process,Window,Pinvoke,Foreground,我正在尝试使用C#中的p/Invoke,使用GetForegroundWindow()捕获新启动的应用程序。但是,我得到的只是explorer.exe窗口句柄,而不是启动的实际进程窗口句柄(如notepad.exe或wordpad.exe) 实际上,当用户同时打开“记事本”时,我试图记录用户输入的文本,我想获得用户试图写入内容的“记事本”实例(如果打开了多个记事本实例)的实际句柄 i、 e我在Windows 7 Ultimate x64上从“开始”菜单启动notepad.exe,并运行基于C#N

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

实际上,当用户同时打开“记事本”时,我试图记录用户输入的文本,我想获得用户试图写入内容的“记事本”实例(如果打开了多个记事本实例)的实际句柄

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

该代码适用于已经打开的windows,但不适用于新启动的任何应用程序实例,如chrome、记事本、写字板或任何其他应用程序。它不是针对正确的应用程序记录文本,而是为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读取为前台窗口。当我输入现有打开的应用程序并且不启动应用程序的新实例时,相同的代码读取正确的应用程序窗口

我在某个地方读到有一些比赛条件的问题。如果是这样,我该如何解决

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


谢谢。

好的。伙计们。GetForeGroundIndow()没有问题。也许这就是为什么我没有得到任何答案。我对问题进行了详细调试并找到了问题所在。答案可以在这里找到,并带有正确的代码


好的。伙计们。GetForeGroundIndow()没有问题。也许这就是为什么我没有得到任何答案。我对问题进行了详细调试并找到了问题所在。答案可以在这里找到,并带有正确的代码


当然,资源管理器是前台窗口。这是处理按键以启动新流程的过程。至于如何解决这个问题,我不想说,因为我真的不明白你想要实现什么。但是,如果您正在挂接键盘输入,难道您不能从键盘挂接内部调用GetForeGroundIndow,这将告诉您键盘输入将在哪里结束。当记事本打开,我在记事本窗口中键入“notepad”时,文本更改事件会记录该文本,稍后我可以看到记录的文本。为了使事情更完美,我通过调用所述方法来更新text changed事件中的“Current Foregound window”。此事件应获取当前前景窗口。i、 e我正在输入的“记事本”应用程序!有什么想法吗???当然,浏览器是前台窗口。这是处理按键以启动新流程的过程。至于如何解决这个问题,我不想说,因为我真的不明白你想要实现什么。但是,如果您正在挂接键盘输入,难道您不能从键盘挂接内部调用GetForeGroundIndow,这将告诉您键盘输入将在哪里结束。当记事本打开,我在记事本窗口中键入“notepad”时,文本更改事件会记录该文本,稍后我可以看到记录的文本。为了使事情更完美,我通过调用所述方法来更新text changed事件中的“Current Foregound window”。此事件应获取当前前景窗口。i、 e我正在输入的“记事本”应用程序!有什么想法吗???