windows | list window handles | Cell 2 | Search

The C# code, located within the window_tracker namespace, retrieves a list of windows that meet certain conditions (e.g., non-zero height, non-empty title, matching process title) using the FindWindows method from the ProgramExtensions class. The filtered window details, including their titles, process names, and foreground status, are then printed to the console.

Run example

npm run import -- "monitor active windows"

monitor active windows

using System;
using System.Linq;

namespace window_tracker
{
    class Program
    {
        static void Main(string[] args)
        {
            var listWindows = ProgramExtensions.FindWindows(delegate (IntPtr wnd, IntPtr param)
            {
                var placement = ProgramExtensions.GetPlacement(wnd);
                var title = ProgramExtensions.GetWindowText(wnd);
                return placement.rcNormalPosition.top != placement.rcNormalPosition.bottom
                    && !String.IsNullOrWhiteSpace(title)
                    && ProgramExtensions.GetProcessTitle(wnd) == title;
            });
            Console.WriteLine(String.Join("\n", listWindows.Select(ptr => (ProgramExtensions.IsForeground(ptr) ? "* " : "" )
                + ProgramExtensions.GetWindowText(ptr) + " - " + ProgramExtensions.GetProcess(ptr).ProcessName)));
        }
    }
}

What the code could have been:

using System;
using System.Linq;
using System.Runtime.InteropServices;

namespace WindowTracker
{
    public class Window
    {
        public IntPtr Handle { get; }
        public string Title { get; }
        public string ProcessName { get; }
        public bool IsForeground { get; }

        public Window(IntPtr handle, string title, string processName, bool isForeground)
        {
            Handle = handle;
            Title = title;
            ProcessName = processName;
            IsForeground = isForeground;
        }
    }

    public static class WindowExtensions
    {
        [DllImport("user32.dll", SetLastError = true)]
        private static extern bool GetWindowPlacement(IntPtr hWnd, ref WINDOWPLACEMENT lpwndpl);

        [StructLayout(LayoutKind.Sequential)]
        private struct WINDOWPLACEMENT
        {
            public int length;
            public int flags;
            public int showCmd;
            public Point rcNormalPosition;
            public Point rcScreenPosition;
            public Size rcClientArea;
        }

        [DllImport("user32.dll", SetLastError = true)]
        private static extern int GetWindowTextLength(IntPtr hWnd);

        [DllImport("user32.dll", SetLastError = true)]
        private static extern int GetWindowText(IntPtr hWnd, StringBuilder text, int count);

        [DllImport("user32.dll", SetLastError = true)]
        private static extern IntPtr GetForegroundWindow();

        [DllImport("psapi.dll", SetLastError = true)]
        private static extern int GetProcessTitle(IntPtr process);

        private static string GetWindowText(IntPtr hWnd)
        {
            var sb = new StringBuilder(256);
            GetWindowText(hWnd, sb, sb.Capacity);
            return sb.ToString();
        }

        private static bool IsForeground(IntPtr hWnd)
        {
            return hWnd == GetForegroundWindow();
        }

        private static string GetProcessName(IntPtr hWnd)
        {
            var process = GetProcess(hWnd);
            return process.ProcessName;
        }

        private static Process GetProcess(IntPtr hWnd)
        {
            var processHandle = OpenProcess(GetProcessHandleAccess(), false, GetProcessId(hWnd));
            var process = Process.GetProcessById(GetProcessId(hWnd));
            CloseHandle(processHandle);
            return process;
        }

        private static int GetProcessId(IntPtr hWnd)
        {
            // This method is Windows-specific and may need to be adjusted for other platforms
            // The following method is using the WindowHandle property of the Process class
            return Process.GetProcessById(GetProcessIdFromHandle(hWnd));
        }

        private static int GetProcessIdFromHandle(IntPtr hWnd)
        {
            // This method is Windows-specific and may need to be adjusted for other platforms
            // The following method is using the WindowHandle property of the Process class
            var process = Process.GetProcessById(GetProcessId(hWnd));
            return process.Id;
        }

        private static string GetProcessTitle(IntPtr hWnd)
        {
            var process = GetProcess(hWnd);
            var title = (string)process.MainWindowTitle;
            if (string.IsNullOrWhiteSpace(title))
            {
                title = process.ProcessName;
            }
            return title;
        }

        private static IntPtr OpenProcess(int access, bool inherit, int processId)
        {
            // This method is Windows-specific and may need to be adjusted for other platforms
            // The following method is using the Process class
            var process = Process.GetProcessById(processId);
            return process.MainModule.Handle;
        }

        private static int GetProcessHandleAccess()
        {
            // This method is Windows-specific and may need to be adjusted for other platforms
            // The following method is using the Process class
            return ProcessAccessFlags.QueryLimitedInformation;
        }

        private static int CloseHandle(IntPtr hObject)
        {
            // This method is Windows-specific and may need to be adjusted for other platforms
            // The following method is using the Process class
            var process = Process.GetProcessById(GetProcessId(hObject));
            return process.CloseMainWindow();
        }

        private static bool IsProcessRunning(int processId)
        {
            // This method is Windows-specific and may need to be adjusted for other platforms
            // The following method is using the Process class
            var process = Process.GetProcessById(processId);
            return process.Responding;
        }

        private static string GetPlacement(IntPtr hWnd)
        {
            var placement = new WINDOWPLACEMENT();
            GetWindowPlacement(hWnd, ref placement);
            return $"{placement.rcNormalPosition.top} {placement.rcNormalPosition.bottom}";
        }

        private static Process[] FindWindows(Func predicate)
        {
            var windows = Process.GetProcesses().Where(p =>!string.IsNullOrEmpty(p.ProcessName)).ToList();
            return windows.Where(w => predicate(new Window(w.MainModule.Handle, w.MainWindowTitle, w.ProcessName, false))).ToArray();
        }
    }

    class Program
    {
        static void Main(string[] args)
        {
            var windows = WindowExtensions.FindWindows(w => w.Handle!= 0 &&!string.IsNullOrWhiteSpace(w.Title)
                && w.Title == w.ProcessName
                && w.IsForeground);
            Console.WriteLine(string.Join("\n", windows.Select(w => $"* {w.Title} - {w.ProcessName}")));
        }
    }
}

Namespace and Class Declaration

The code is written in C# and resides in the window_tracker namespace within the Program class.

Using Directives

The code imports the following namespaces:

Main Method

The Main method is the entry point of the program, responsible for executing the application.

FindWindows Method Call

The FindWindows method from the ProgramExtensions class is called, passing a delegate that filters windows based on the following conditions:

  1. The window's normal position has a non-zero height.
  2. The window's title is not empty or whitespace-only.
  3. The window's title matches its process title.

Console Output

The filtered window pointers are then enumerated and their details are printed to the console using String.Join. For each window, the following information is displayed:

  1. A '*' character if the window is in the foreground.
  2. The window's title.
  3. The window's process name.

Note

The ProgramExtensions class is not shown in the provided code, but it is assumed to contain methods for interacting with windows, such as FindWindows, GetPlacement, GetWindowText, IsForeground, GetProcess, and GetProcessTitle.