Jer*_*emy 8 .net c# process window-handles
使用Microsoft Spy ++,我可以看到以下属于某个进程的窗口:
处理XYZ窗口句柄,以树形式显示,就像Spy ++一样,给了我:
A
B
C
D
E
F
G
H
I
J
K
Run Code Online (Sandbox Code Playgroud)
我可以得到进程,MainWindowHandle属性指向窗口F的句柄.如果我使用枚举子窗口我可以得到G到K的窗口句柄列表,但我无法弄清楚如何找到窗口A到D的句柄.如何枚举不是Process对象的MainWindowHandle指定的句柄的子窗口?
要枚举我正在使用win32调用:
[System.Runtime.InteropServices.DllImport(strUSER32DLL)]
public static extern int EnumChildWindows(IntPtr hWnd, WindowCallBack pEnumWindowCallback, int iLParam);
Run Code Online (Sandbox Code Playgroud)
SLa*_*aks 10
通过IntPtr.Zero为hWnd获取系统中的每根窗口句柄.
然后,您可以通过调用来检查Windows的所有者进程GetWindowThreadProcessId.
对于每个仍在疑惑的人来说,这就是答案:
List<IntPtr> GetRootWindowsOfProcess(int pid)
{
List<IntPtr> rootWindows = GetChildWindows(IntPtr.Zero);
List<IntPtr> dsProcRootWindows = new List<IntPtr>();
foreach (IntPtr hWnd in rootWindows)
{
uint lpdwProcessId;
WindowsInterop.User32.GetWindowThreadProcessId(hWnd, out lpdwProcessId);
if (lpdwProcessId == pid)
dsProcRootWindows.Add(hWnd);
}
return dsProcRootWindows;
}
public static List<IntPtr> GetChildWindows(IntPtr parent)
{
List<IntPtr> result = new List<IntPtr>();
GCHandle listHandle = GCHandle.Alloc(result);
try
{
WindowsInterop.Win32Callback childProc = new WindowsInterop.Win32Callback(EnumWindow);
WindowsInterop.User32.EnumChildWindows(parent, childProc, GCHandle.ToIntPtr(listHandle));
}
finally
{
if (listHandle.IsAllocated)
listHandle.Free();
}
return result;
}
private static bool EnumWindow(IntPtr handle, IntPtr pointer)
{
GCHandle gch = GCHandle.FromIntPtr(pointer);
List<IntPtr> list = gch.Target as List<IntPtr>;
if (list == null)
{
throw new InvalidCastException("GCHandle Target could not be cast as List<IntPtr>");
}
list.Add(handle);
// You can modify this to check to see if you want to cancel the operation, then return a null here
return true;
}
Run Code Online (Sandbox Code Playgroud)
对于WindowsInterop:
public delegate bool Win32Callback(IntPtr hwnd, IntPtr lParam);
Run Code Online (Sandbox Code Playgroud)
对于WindowsInterop.User32:
[DllImport("user32.dll")]
public static extern uint GetWindowThreadProcessId(IntPtr hWnd, out uint lpdwProcessId);
[DllImport("user32.Dll")]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool EnumChildWindows(IntPtr parentHandle, Win32Callback callback, IntPtr lParam);
Run Code Online (Sandbox Code Playgroud)
现在可以通过GetChildWindows简单地获取GetRootWindowsOfProcess的每个根窗口,以及它们的子节点.