none
使用EnumWindowsAPI函数查找已知进程的窗口句柄但是时有时无的不知道为什么。 RRS feed

  • 问题

  • 如题,我希望用enumwindows或者用enumthreadwindows寻找已知进程的主窗口句柄。但是有的时候就是找不到,进程明明是正确的。下面是回调函数。

    private bool EnumWindowsCallBack(IntPtr hWnd, int lParam)
            {
                uint pid;
                Win32Api.GetWindowThreadProcessId(hWnd, out pid);
                if (pid != lParam) { return true; }//确认是否为登录遍历的两个进程如果不是直接返回如果是继续操作
                if (Win32Api.IsWindow(hWnd) && Win32Api.IsWindowVisible(hWnd))
                {
                    Console.WriteLine("当前窗口句柄:{0}为可见", hWnd.ToString("X"));
                    string className = Win32Api.GetClassName(hWnd);
                    if (!className.Equals("TXGuiFoundation")) return true;
                    string title = Win32Api.GetText(hWnd);
                    Console.WriteLine(title + "classname:::" + className);
                    if (!title.Equals("QQ")) return true;
                    QQLoginPtr = hWnd;//当所有条件都成立的时候就确定了这个窗口就是需要的登录窗口
                    return false;
                }
                return true;
            }

    请大神们给解释下这是什么原因,再此表示十分感谢。

    补充一下我是通过遍历一个进程列表来查找的。 List<Process> p_list = GetNewProcess(p_old);就是这么个玩应。

    • 已编辑 Schme 2014年12月29日 10:09 补充
    2014年12月29日 9:53

答案

  • 您好,很高兴看到您的回答,但是我有个疑问,因为QQ登录进程和QQ主程序进程是一样的光从进程上无法分辨出是哪个而且QQ登录窗口具有两个进程。这该怎么做呢?

    一个窗口应该不会同时属于两个进程,如果通过进程的MainWindowHandle很难确定窗口的话也可以尝试一下使用FindWindow来根据窗口的classname和windowname来判断,通过spy++可以获取到这两个属性:

    http://msdn.microsoft.com/zh-cn/library/dd460750.aspx

    也可以尝试一下以下的代码,我的机器上可以正确抓取到窗口句柄,和spy++抓取到的结果是一样的

    static void Main(string[] args)
            {
                var windows = FindWindowsWithText("Notepad");
    
                Console.Read();
            }
    
            private delegate bool EnumWindowsProc(IntPtr hWnd, IntPtr lParam);
    
            [DllImport("user32.dll", CharSet = CharSet.Unicode)]
            private static extern int GetWindowText(IntPtr hWnd, StringBuilder strText, int maxCount);
    
            [DllImport("user32.dll", CharSet = CharSet.Unicode)]
            private static extern int GetWindowTextLength(IntPtr hWnd);
    
            [DllImport("user32.dll")]
            private static extern bool EnumWindows(EnumWindowsProc enumProc, IntPtr lParam);
    
            public static string GetWindowText(IntPtr hWnd)
            {
                int size = GetWindowTextLength(hWnd);
                if (size++ > 0)
                {
                    var builder = new StringBuilder(size);
                    GetWindowText(hWnd, builder, builder.Capacity);
                    return builder.ToString();
                }
    
                return String.Empty;
            }
    
            public static IEnumerable<IntPtr> FindWindowsWithText(string titleText)
            {
                IntPtr found = IntPtr.Zero;
                List<IntPtr> windows = new List<IntPtr>();
    
                EnumWindows(delegate(IntPtr wnd, IntPtr param)
                {
                    if (GetWindowText(wnd).Contains(titleText))
                    {
                        windows.Add(wnd);
                    }
                    return true;
                },
                            IntPtr.Zero);
    
                return windows;
            }


    We are trying to better understand customer views on social support experience, so your participation in this interview project would be greatly appreciated if you have time. Thanks for helping make community forums a great place.
    Click HERE to participate the survey.


    2014年12月30日 8:20
    版主

全部回复

  • 你好:

    你这个方法的主要目的就是获取QQ登陆窗口的句柄是吧?我电脑上无法安装QQ,但是我觉得有一个更为简便的方法你可以试一下

    http://msdn.microsoft.com/en-us/library/system.diagnostics.process.mainwindowhandle(v=vs.110).aspx

    你可以遍历所有进程,根据进程名称来判断是否是QQ登陆窗口所在的进程,如果是的话通过Process.MainWindowHandle这个属性获取登陆窗口的句柄。

    foreach (Process p in Process.GetProcesses())
    {
        Console.WriteLine(p.MainWindowHandle);
    }


    We are trying to better understand customer views on social support experience, so your participation in this interview project would be greatly appreciated if you have time. Thanks for helping make community forums a great place.
    Click HERE to participate the survey.


    2014年12月30日 2:05
    版主
  • 您好,很高兴看到您的回答,但是我有个疑问,因为QQ登录进程和QQ主程序进程是一样的光从进程上无法分辨出是哪个而且QQ登录窗口具有两个进程。这该怎么做呢?
    2014年12月30日 4:53
  • 您好,很高兴看到您的回答,但是我有个疑问,因为QQ登录进程和QQ主程序进程是一样的光从进程上无法分辨出是哪个而且QQ登录窗口具有两个进程。这该怎么做呢?

    一个窗口应该不会同时属于两个进程,如果通过进程的MainWindowHandle很难确定窗口的话也可以尝试一下使用FindWindow来根据窗口的classname和windowname来判断,通过spy++可以获取到这两个属性:

    http://msdn.microsoft.com/zh-cn/library/dd460750.aspx

    也可以尝试一下以下的代码,我的机器上可以正确抓取到窗口句柄,和spy++抓取到的结果是一样的

    static void Main(string[] args)
            {
                var windows = FindWindowsWithText("Notepad");
    
                Console.Read();
            }
    
            private delegate bool EnumWindowsProc(IntPtr hWnd, IntPtr lParam);
    
            [DllImport("user32.dll", CharSet = CharSet.Unicode)]
            private static extern int GetWindowText(IntPtr hWnd, StringBuilder strText, int maxCount);
    
            [DllImport("user32.dll", CharSet = CharSet.Unicode)]
            private static extern int GetWindowTextLength(IntPtr hWnd);
    
            [DllImport("user32.dll")]
            private static extern bool EnumWindows(EnumWindowsProc enumProc, IntPtr lParam);
    
            public static string GetWindowText(IntPtr hWnd)
            {
                int size = GetWindowTextLength(hWnd);
                if (size++ > 0)
                {
                    var builder = new StringBuilder(size);
                    GetWindowText(hWnd, builder, builder.Capacity);
                    return builder.ToString();
                }
    
                return String.Empty;
            }
    
            public static IEnumerable<IntPtr> FindWindowsWithText(string titleText)
            {
                IntPtr found = IntPtr.Zero;
                List<IntPtr> windows = new List<IntPtr>();
    
                EnumWindows(delegate(IntPtr wnd, IntPtr param)
                {
                    if (GetWindowText(wnd).Contains(titleText))
                    {
                        windows.Add(wnd);
                    }
                    return true;
                },
                            IntPtr.Zero);
    
                return windows;
            }


    We are trying to better understand customer views on social support experience, so your participation in this interview project would be greatly appreciated if you have time. Thanks for helping make community forums a great place.
    Click HERE to participate the survey.


    2014年12月30日 8:20
    版主