.NET C#: Find a Process and Maximize or Minimize All Process Windows

1/21/2015 6:52:18 PM

The following code minimizes or maximizes all windows for a process. It takes a process name, iterates over all windows using EnumWindows, determines the current window placement using GetWindowPlacement, and maximizes or minimizes the window using ShowWindowAsync.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Runtime.InteropServices;
using System.Diagnostics;

namespace MinimizeWindow
{
    class Program
    {
        static void Main(string[] args)
        {
            CloseFirefoxWindow();
        }        


        public static void CloseFirefoxWindow()
        {
            string processName = "firefox";
            CloseWindow(processName);
        }


        public static void CloseWindow(string processName)
        {            
            Process[] processes = Process.GetProcessesByName(processName);
            if (processes.Length > 0)
            {
                foreach (var process in processes)
                {                    
                    IDictionary<IntPtr, string> windows = List_Windows_By_PID(process.Id);
                    foreach (KeyValuePair<IntPtr, string> pair in windows)
                    {
                        var placement = new WINDOWPLACEMENT();
                        GetWindowPlacement(pair.Key, ref placement);

                        if (placement.showCmd == SW_SHOWMINIMIZED)
                        {
                            //if minimized, show maximized
                            ShowWindowAsync(pair.Key, SW_SHOWMAXIMIZED);
                        }
                        else
                        {
                            //default to minimize
                            ShowWindowAsync(pair.Key, SW_SHOWMINIMIZED);
                        }
                    }
                }
            }
        }


        private const int SW_SHOWNORMAL = 1;
        private const int SW_SHOWMINIMIZED = 2;
        private const int SW_SHOWMAXIMIZED = 3;

        private struct WINDOWPLACEMENT
        {
            public int length;
            public int flags;
            public int showCmd;
            public System.Drawing.Point ptMinPosition;
            public System.Drawing.Point ptMaxPosition;
            public System.Drawing.Rectangle rcNormalPosition;
        }

        [DllImport("user32.dll")]
        private static extern bool ShowWindowAsync(IntPtr hWnd, int nCmdShow);

        private delegate bool EnumWindowsProc(IntPtr hWnd, int lParam);

        [DllImport("user32.dll", SetLastError = true)]
        private static extern uint GetWindowThreadProcessId(IntPtr hWnd, out uint lpdwProcessId);

        [DllImport("USER32.DLL")]
        private static extern bool EnumWindows(EnumWindowsProc enumFunc, int lParam);

        [DllImport("USER32.DLL")]
        private static extern int GetWindowText(IntPtr hWnd, StringBuilder lpString, int nMaxCount);

        [DllImport("USER32.DLL")]
        private static extern int GetWindowTextLength(IntPtr hWnd);

        [DllImport("USER32.DLL")]
        private static extern bool IsWindowVisible(IntPtr hWnd);

        [DllImport("USER32.DLL")]
        private static extern IntPtr GetShellWindow();

        [DllImport("USER32.DLL")]
        private static extern bool GetWindowPlacement(IntPtr hWnd, ref WINDOWPLACEMENT lpwndpl);


        public static IDictionary<IntPtr, string> List_Windows_By_PID(int processID)
        {
            IntPtr hShellWindow = GetShellWindow();
            Dictionary<IntPtr, string> dictWindows = new Dictionary<IntPtr, string>();

            EnumWindows(delegate(IntPtr hWnd, int lParam)
            {
                //ignore the shell window
                if (hWnd == hShellWindow)
                {
                    return true;
                }

                //ignore non-visible windows
                if (!IsWindowVisible(hWnd))
                {
                    return true;
                }

                //ignore windows with no text
                int length = GetWindowTextLength(hWnd);
                if (length == 0)
                {
                    return true;
                }

                uint windowPid;
                GetWindowThreadProcessId(hWnd, out windowPid);

                //ignore windows from a different process
                if (windowPid != processID)
                {
                    return true;
                }

                StringBuilder stringBuilder = new StringBuilder(length);
                GetWindowText(hWnd, stringBuilder, length + 1);
                dictWindows.Add(hWnd, stringBuilder.ToString());

                return true;

            }, 0);

            return dictWindows;
        }        
    }
}