找到以前关注的应用程序 - WinAPI

时间:2010-01-19 11:23:20

标签: c# winapi

我在一个相关的问题中回答了这个问题 - 但这是一个额外的问题,我遇到了麻烦,我需要更多最近的答案......

基本上我有一个应用程序在屏幕上保持打开状态,用户可以在我的应用程序进入三个第三方应用程序之一后按下我的应用程序上的按钮。

当他们点击我的应用程序上的按钮时,我需要确定他们上次使用的三个应用程序中的哪一个,以便知道要与哪个数据库通信。我已经走下了查看GetForeGroundWindow和GetWindow的路线,但是我从GetWindow获得的Window句柄总是引用一个标题为M的窗口。我使用了Managed Windows API工具中的Winternal Explorer工具,我可以找到M句柄返回,它是我追求的过程的“孩子” - 但是从这个句柄我不能得到进程名称。

我已经使用简单的Windows窗体完成了一个小示例应用程序 - 然后我开始使用它然后使记事本成为焦点,然后单击我的按钮并获得句柄 - 但是当查看所有进程的MainWindowHandle时,它没有列出,但使用Winternal Explorer我可以看到这是记事本过程的子过程。

有关为什么我只返回此子进程句柄而不是实际进程句柄的任何建议?

示例代码如下 - 在Windows XP sp 3计算机上运行

using System;
using System.Runtime.InteropServices;
using System.Windows.Forms;

namespace TestWindowsAPI
{
    public partial class Form1 : Form
    {
        [DllImport("user32.dll")]
        public static extern IntPtr GetForegroundWindow();

        [DllImport("user32.dll", SetLastError = true)]
        static extern IntPtr GetWindow(IntPtr hWnd, uint uCmd);

        public Form1()
        {
            InitializeComponent();
        }

        private void button1_Click(object sender, EventArgs e)
        {
            IntPtr thisWindow = GetForegroundWindow();
            IntPtr lastWindow = GetWindow(thisWindow, 2);

            tbThisWindow.Text = thisWindow.ToString();
            tbLastWindow.Text = lastWindow.ToString();
        }
    }
}

3 个答案:

答案 0 :(得分:2)

您可以使用GetWindowThreadProcessId从(子)窗口句柄获取进程ID:

uint lastProcess;
GetWindowThreadProcessId(lastWindow, out lastProcess);

答案 1 :(得分:2)

Pent Ploompuu - 这是当场的 - 出色的工作!干杯

对于其他任何人 - 这就是我的测试功能最终看起来像:

private void button1_Click(object sender, EventArgs e)
    {
        IntPtr thisWindow = GetForegroundWindow();
        IntPtr lastWindow = GetWindow(thisWindow, 2);

        uint processID = 0;
        var parentWindow = GetWindowThreadProcessId(lastWindow, out processID);

        tbThisWindow.Text = thisWindow.ToString();
        tbLastWindow.Text = lastWindow.ToString();
        tbParentWindow.Text = parentWindow.ToString();

        tbLastProcess.Text = processID.ToString();
        var processName = from cp in Process.GetProcesses() where cp.Id == processID select cp.ProcessName;

        tbParentName.Text = processName.FirstOrDefault();
    }

答案 2 :(得分:0)

尝试覆盖每个程序的WndProc(或添加IMessageFilter),并在发送特定消息时返回“app ID”。然后只需在窗口句柄上使用SendMessage即可获取应用程序ID。