Skip to content

Instantly share code, notes, and snippets.

@emoacht
Last active July 21, 2024 07:04
Show Gist options
  • Save emoacht/6b38452df693493f967f29c965684f81 to your computer and use it in GitHub Desktop.
Save emoacht/6b38452df693493f967f29c965684f81 to your computer and use it in GitHub Desktop.
Enumerate all windows on the desktop. To produce correct geometries, app.manifest must be added.
<?xml version="1.0" encoding="utf-8"?>
<assembly manifestVersion="1.0" xmlns="urn:schemas-microsoft-com:asm.v1">
<assemblyIdentity version="1.0.0.0" name="MyApplication.app"/>
<trustInfo xmlns="urn:schemas-microsoft-com:asm.v2">
<security>
<requestedPrivileges xmlns="urn:schemas-microsoft-com:asm.v3">
<requestedExecutionLevel level="asInvoker" uiAccess="false" />
</requestedPrivileges>
</security>
</trustInfo>
<compatibility xmlns="urn:schemas-microsoft-com:compatibility.v1">
<application>
<!-- Windows 10 -->
<supportedOS Id="{8e0f7a12-bfb3-4fe8-b9a5-48fd50a15a9a}" />
</application>
</compatibility>
<application xmlns="urn:schemas-microsoft-com:asm.v3">
<windowsSettings>
<dpiAwareness xmlns="http://schemas.microsoft.com/SMI/2016/WindowsSettings">PerMonitorV2, PerMonitor</dpiAwareness>
</windowsSettings>
</application>
</assembly>
using System.Runtime.InteropServices;
using System.Text;
internal class Program
{
static void Main(string[] args)
{
Console.WriteLine("Generation, Name, X,Y,Width,Height");
foreach (var w in GetAllWindows())
{
Console.WriteLine(@$"{new string(' ', w.generation)}{w.generation}, {w.name}, {w.rect.left},{w.rect.top},{w.rect.Width},{w.rect.Height}");
}
}
static IReadOnlyList<(int generation, string name, RECT rect)> GetAllWindows()
{
var list = new List<(int generation, string name, RECT rect)>();
EnumWindows(
Proc,
0);
return list.AsReadOnly();
bool Proc(nint windowHandle, nint lParam)
{
var buffer = new StringBuilder(256);
if (GetClassName(
windowHandle,
buffer,
buffer.Capacity) > 0)
{
int currentGeneration = (int)lParam;
int nextGeneration = currentGeneration + 1;
var name = buffer.ToString();
GetWindowRect(
windowHandle,
out RECT rect);
list.Add((currentGeneration, name, rect));
EnumChildWindows(
windowHandle,
Proc,
new IntPtr(nextGeneration));
}
return true;
}
}
#region Win32
[StructLayout(LayoutKind.Sequential)]
struct RECT
{
public int left;
public int top;
public int right;
public int bottom;
public readonly int Width => (right - left);
public readonly int Height => (bottom - top);
}
[DllImport("User32.dll", SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
static extern bool EnumWindows(
EnumWindowsProc lpEnumFunc,
nint lParam);
[DllImport("User32.dll")]
[return: MarshalAs(UnmanagedType.Bool)]
static extern bool EnumChildWindows(
nint hWndParent,
EnumWindowsProc lpEnumFunc,
nint lParam);
[return: MarshalAs(UnmanagedType.Bool)]
private delegate bool EnumWindowsProc(
nint hWnd,
nint lParam);
[DllImport("User32.dll", SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
static extern bool GetWindowRect(
nint hWnd,
out RECT lpRect);
[DllImport("User32.dll", CharSet = CharSet.Unicode, SetLastError = true)]
static extern int GetClassName(
nint hWnd,
StringBuilder lpClassName,
int nMaxCount);
#endregion
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment