Last active
July 21, 2024 07:04
-
-
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.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?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> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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