我想做一個小應用程序來枚舉每個進程線程中的每個窗口名稱在控制檯中。C#試圖枚舉每個進程線程的每個窗口
我目前使用的代碼可以在Windows 7機器上正常工作,但由於某種原因,它在沒有任何堆棧跟蹤或錯誤消息的情況下在Windows 10中查找,我試圖添加幾乎所有內部的try-catch,但我didn我也沒有收到任何消息,所以我迷路了。
下面是代碼:
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;
}
}
}
爲什麼它可能卡住任何想法?
UPDATE
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;
}
}
}
謝謝大家。
我相信這與了Windows 10應用程序沙箱和應用程序,但我做的不確定。我知道我們無法深入瞭解我們使用的方式,但我不知道這樣做的正確方法。 Windows 10使用了很多虛擬環境來託管應用程序,所以我只是在這裏猜測......請不要將此作爲任何答案。 –
感謝您的回答邁克爾Pucket II,我試着在另一臺機器與Windows 10和工作正常,但看起來像代碼隨機失敗也在Windows 7沒有任何消息/痕跡/錯誤...我真的不知道在哪裏開始解決我的問題。 –
我有一個想法。你的windowHandles = null已經。 EnumerateProcessWindowHandles(進程)不會失敗,但仍然返回null。然後當你輸入foreach(var handle在windowHandles中)它會崩潰。你應該得到一個錯誤,但如果這是部署你可能不會。我將windowHandles設置爲一個空的枚舉,以便foreach循環至少有一個零計數值,並且永遠不會有空值。這是我能夠立即注意到的唯一缺陷,如果是我,就必須從那裏開始。 –