You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Windows 11下C#代码无法最小化所有记事本实例的问题求助

Windows 11下以管理员权限运行时无法最小化所有记事本实例的解决方案

问题描述

我编写了一段C#代码用于最小化所有打开的记事本实例,在Windows 10上运行正常,但在Windows 11中以管理员权限运行生成的EXE时,仅能最小化3个打开实例中的一个。代码如下:

class Program
{
    private const int SW_SHOWNORMAL = 1;
    private const int SW_SHOWMINIMIZED = 2;
    private const int SW_SHOWMAXIMIZED = 3;

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

    [DllImport("user32.dll")]
    private static extern bool MinimizeWindow(System.IntPtr hwnd);

    static void Main(string[] args)
    {
        System.Diagnostics.Process thisProcess =
        System.Diagnostics.Process.GetCurrentProcess();
        System.Diagnostics.Process[] processes =
        System.Diagnostics.Process.GetProcessesByName("notepad");

        foreach (System.Diagnostics.Process process in processes)
        {
            if (process == thisProcess) 
                continue;

            System.IntPtr handle = process.MainWindowHandle;

            if (handle == System.IntPtr.Zero) 
                continue;

            IntPtr s1 = process.MainWindowHandle;
            ShowWindowAsync(s1, SW_SHOWMINIMIZED);
        }
    }
}

问题原因

Windows 11的UAC权限隔离机制比Windows 10更严格:当程序以管理员权限运行时,它只能直接访问同权限级别的进程,普通权限启动的记事本进程会被系统隔离。这导致Process.GetProcessesByName("notepad")要么只能获取到同权限的实例,要么无法获取到普通权限进程的有效MainWindowHandle(返回IntPtr.Zero),最终只能最小化其中一个实例。

解决方案

改用EnumWindows枚举系统所有顶级窗口,通过窗口关联的进程ID判断是否为记事本,再执行最小化操作。这种方式不受权限隔离限制,能覆盖所有可见的记事本窗口。

修正后的代码:

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

class Program
{
    private const int SW_SHOWMINIMIZED = 2;

    [DllImport("user32.dll")]
    private static extern bool EnumWindows(EnumWindowsProc enumProc, IntPtr lParam);

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

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

    [DllImport("user32.dll")]
    private static extern bool IsWindowVisible(IntPtr hWnd);

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

    static void Main(string[] args)
    {
        EnumWindows((hWnd, lParam) =>
        {
            if (IsWindowVisible(hWnd))
            {
                GetWindowThreadProcessId(hWnd, out uint processId);
                try
                {
                    using (var process = Process.GetProcessById((int)processId))
                    {
                        if (string.Equals(process.ProcessName, "notepad", StringComparison.OrdinalIgnoreCase))
                        {
                            ShowWindowAsync(hWnd, SW_SHOWMINIMIZED);
                        }
                    }
                }
                catch (ArgumentException)
                {
                    // 进程已退出,忽略该窗口
                }
            }
            return true;
        }, IntPtr.Zero);
    }
}

关键说明

  • EnumWindows:遍历系统所有顶级窗口,不受权限隔离影响,能获取到所有可见窗口的句柄。
  • IsWindowVisible:过滤不可见窗口,避免处理后台或隐藏的窗口。
  • GetWindowThreadProcessId:通过窗口句柄获取对应的进程ID,进而验证进程是否为记事本。
  • 使用using语句管理Process对象:确保资源及时释放,避免内存泄漏。
  • 捕获ArgumentException:处理枚举过程中进程已退出的情况,防止程序崩溃。

内容的提问来源于stack exchange,提问作者Pankaj

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.29 00:27:05