C#控制Windows应用程序最大最小化的实现与应用

背景

在开发一个WinForm混合使用WPF控件的应用程序时,遇到了一个特殊的问题:在某些电脑上运行较长一段时间后,WPF控件会变成一片空白,特别是在最小化再切到软件显示时会有几率出现这样的问题。出现之后只能重启软件才能恢复。为了增加复现概率,我编写了一个自动控制应用程序最大最小化的工具,通过频繁切换窗口状态来加速复现。最后发现这是核显驱动的问题,在重装一个稳定版本的核显驱动后就没出现了。

核心代码

using System;
using System.Diagnostics;
using System.Runtime.InteropServices;

namespace 控制指定应用程序最大最小化
{
    internal class Helper
    {
        [DllImport("user32.dll", EntryPoint = "PostMessage")]
        private static extern int PostMessage(IntPtr hwnd, int wMsg, int wParam, int lParam);
        
        [DllImport("User32.dll ", EntryPoint = "FindWindow")]
        private static extern IntPtr FindWindow(string lpClassName, string lpWindowName);
        
        private const int WM_SYSCOMMAND = 0x112;
        private const int SC_MINIMIZE = 0xF020;
        private const int SC_MAXIMIZE = 0xF030;
        private const int SC_RESTORE = 0xF120;        

        /// <summary>
        /// 最小化其他应用程序
        /// </summary>
        /// <param name="processName"></param>
        public static void MinimizeAppication(string processName)
        {
            Process[] processs = Process.GetProcessesByName(processName);
            if (processs != null)
            {
                foreach (Process p in processs)
                {
                    IntPtr handle = FindWindow(null, p.MainWindowTitle);
                    PostMessage(handle, WM_SYSCOMMAND, SC_MINIMIZE, 0);
                }
            }
        }

        /// <summary>
        /// 最大化其他应用程序
        /// </summary>
        /// <param name="processName"></param>
        public static void MaximizeAppication(string processName)
        {
            Process[] processs = Process.GetProcessesByName(processName);
            if (processs != null)
            {
                foreach (Process p in processs)
                {
                    IntPtr handle = FindWindow(null, p.MainWindowTitle);
                    PostMessage(handle, WM_SYSCOMMAND, SC_MAXIMIZE, 0);
                }
            }
        }

        public static void RestoreAppication(string processName)
        {
            Process[] processs = Process.GetProcessesByName(processName);
            if (processs != null)
            {
                foreach (Process p in processs)
                {
                    IntPtr handle = FindWindow(null, p.MainWindowTitle);
                    PostMessage(handle, WM_SYSCOMMAND, SC_RESTORE, 0);
                }
            }
        }
    }
}

示例

// 最小化记事本应用
Helper.MinimizeAppication("notepad");

// 最大化记事本应用
Helper.MaximizeAppication("notepad");

// 恢复记事本应用窗口
Helper.RestoreAppication("notepad");
static void Main(string[] args)
        {
            string str = ConfigurationManager.AppSettings["processName"];
            if (string.IsNullOrEmpty(str)) { Console.WriteLine($"未找到processName:{str}");Console.ReadKey(); return; }
             Task.Run(async () =>
            {
                while (true)
                {
                    Helper.RestoreAppication(str);
                    await Task.Delay(500);
                    Helper.MinimizeAppication(str);
                    await Task.Delay(500);
                }
            }).Wait();
            Console.ReadKey();
        }

扩展

后续可扩展:

  1. 窗口激活:将指定应用程序窗口置于前台
  2. 窗口移动:移动窗口到指定位置
  3. 窗口大小调整:调整窗口到指定大小
  4. 窗口关闭:关闭指定应用程序窗口
posted @ 2026-03-20 17:42  (*_^)?  阅读(8)  评论(0)    收藏  举报