C#试图枚举每个进程线程的每个窗口

时间:2017-01-30 03:12:47

标签: c#

我正在尝试创建一个小应用程序来在控制台中枚举每个进程线程的每个窗口名称。

我目前正在使用这个代码在Windows 7机器上工作正常但由于某种原因它在没有任何堆栈跟踪或错误消息的情况下卡在Windows 10上,我试图在try-catch中添加几乎所有内容但我没有'也得到任何消息,所以我迷路了。

以下是代码:

    using System;
    using System.Collections.Generic;
    using System.Diagnostics;
    using System.Runtime.InteropServices;
    using System.Text;

    namespace ConsoleApplication3
    {
        class Program
        {
            private delegate bool EnumThreadDelegate(IntPtr hWnd, IntPtr lParam);

            [DllImport("user32.dll")]
            private static extern bool EnumThreadWindows(int dwThreadId, EnumThreadDelegate lpfn, IntPtr lParam);

            [DllImport("user32.dll", CharSet = CharSet.Auto)]
            private static extern IntPtr SendMessage(IntPtr hWnd, uint Msg, int wParam, StringBuilder lParam);

            static void Main(string[] args)
            {
                Process[] processes = Process.GetProcesses();
                Console.WriteLine("Detected: " + processes.Length + " processes.");
                foreach (Process process in processes)
                {
                    IEnumerable<IntPtr> windowHandles = null;
                    try
                    {
                        windowHandles = EnumerateProcessWindowHandles(process);
                    }
                    catch (Exception e)
                    {
                        Console.WriteLine(e.StackTrace);
                        continue;
                    }

                    Console.WriteLine("Checking process" + process.ProcessName);
                    foreach (var handle in windowHandles)
                    {
                        StringBuilder message = new StringBuilder();
                        try
                        {
                            SendMessage(handle, 0x000D, message.Capacity, message);
                        }
                        catch (Exception e)
                        {
                            Console.WriteLine(e.StackTrace);
                            continue;
                        }
                        if (message.Length == 0)
                        {
                            continue;
                        }
                        Console.WriteLine("Window name: " + message.ToString());
                    }
                }
                Console.WriteLine("Finished!");
                Console.ReadLine();
            }

            private static IEnumerable<IntPtr> EnumerateProcessWindowHandles(Process process)
            {
                List<IntPtr> handles = new List<IntPtr>();

                ProcessThreadCollection threads = null;
                try
                {
                    threads = process.Threads;
                }
                catch (Exception e)
                {
                    Console.WriteLine(e.StackTrace);
                    return handles;
                }

                foreach (ProcessThread thread in threads)
                {
                    try
                    {
                        EnumThreadWindows(thread.Id, (hWnd, lParam) => { handles.Add(hWnd); return true; }, IntPtr.Zero);
                    }
                    catch (Exception e)
                    {
                        Console.WriteLine(e.StackTrace);
                        continue;
                    }
                }
                return handles;
            }
        }
    }

有关它为什么会卡住的任何想法?

更新

    using System;
    using System.Collections.Generic;
    using System.Diagnostics;
    using System.Runtime.InteropServices;
    using System.Text;

    namespace ConsoleApplication3
    {
        class Program
        {
            private delegate bool EnumThreadDelegate(IntPtr hWnd, IntPtr lParam);

            [DllImport("user32.dll")]
            [return: MarshalAs(UnmanagedType.Bool)]
            private static extern bool EnumThreadWindows(int dwThreadId, EnumThreadDelegate lpfn, IntPtr lParam);

            [DllImport("user32.dll", CharSet = CharSet.Auto)]
            private static extern IntPtr SendMessage(IntPtr hWnd, uint Msg, int wParam, StringBuilder lParam);

            [DllImport("user32.dll")]
            [return: MarshalAs(UnmanagedType.Bool)]
            private static extern bool IsWindowVisible(IntPtr handle);

            static void Main(string[] args)
            {
                Process[] processes = Process.GetProcesses();
                Console.WriteLine("Detected: " + processes.Length + " processes.");
                foreach (Process process in processes)
                {
                    IEnumerable<IntPtr> windowHandles = null;
                    try
                    {
                        windowHandles = EnumerateProcessWindowHandles(process);
                    }
                    catch (Exception e)
                    {
                        Console.WriteLine(e.StackTrace);
                        continue;
                    }

                    Console.WriteLine("Checking process: " + process.ProcessName);
                    foreach (IntPtr handle in windowHandles)
                    {
                        if (handle == null)
                        {
                            continue;
                        }
                        if (!IsWindowVisible(handle))
                        {
                            continue;
                        }
                        StringBuilder message = new StringBuilder();
                        int capacity = 0;
                        try
                        {
                            capacity = message.Capacity;
                        }
                        catch(Exception e)
                        {
                            Console.WriteLine(e.StackTrace);
                            continue;
                        }
                        try
                        {
                            SendMessage(handle, 0x000D, capacity, message);
                        }
                        catch (Exception e)
                        {
                            Console.WriteLine(e.StackTrace);
                            continue;
                        }
                        if (message.Length == 0)
                        {
                            continue;
                        }
                        Console.WriteLine("Window name: " + message.ToString());
                    }
                }
                Console.WriteLine("Finished!");
                Console.ReadLine();
            }

            private static IEnumerable<IntPtr> EnumerateProcessWindowHandles(Process process)
            {
                List<IntPtr> handles = new List<IntPtr>();

                ProcessThreadCollection threads = null;
                try
                {
                    threads = process.Threads;
                }
                catch (Exception e)
                {
                    Console.WriteLine(e.StackTrace);
                    return handles;
                }

                foreach (ProcessThread thread in threads)
                {
                    if (thread == null)
                    {
                        continue;
                    }

                    int threadId = 0;
                    try
                    {
                        threadId = thread.Id;
                    }
                    catch(Exception e)
                    {
                        Console.WriteLine(e.StackTrace);
                        continue;
                    }
                    try
                    {
                        EnumThreadWindows(threadId, (hWnd, lParam) => { handles.Add(hWnd); return true; }, IntPtr.Zero);
                    }
                    catch (Exception e)
                    {
                        Console.WriteLine(e.StackTrace);
                        continue;
                    }
                }
                return handles;
            }
        }
    }

谢谢大家。

1 个答案:

答案 0 :(得分:0)

如果问题仍然存在,请尝试以管理员身份运行您的控制台应用程序我建议使用API​​ GetLastError,这就是它的作用:

  

检索调用线程的最后错误代码值。最后一个错误代码是基于每个线程维护的。多个线程不会覆盖彼此的最后一个错误代码。

尝试阅读该值以了解问题,请尝试此链接以获取有关如何使用它的指导: https://msdn.microsoft.com/en-us/library/windows/desktop/ms679360(v=vs.85).aspx