EnumWindows返回已关闭的Windows应用商店应用程序

Nic*_*rin 5 c# winapi

使用此代码:

internal static List<DetectedWindow> EnumerateWindows()
{
    var shellWindow = GetShellWindow();

    var windows = new List<DetectedWindow>();

    EnumWindows(delegate (IntPtr handle, int lParam)
    {
        if (handle == shellWindow)
            return true;

        if (!IsWindowVisible(handle))
            return true;

        if (IsIconic(handle))
            return true;

        var length = GetWindowTextLength(handle);

        if (length == 0)
            return true;

        var builder = new StringBuilder(length);

        GetWindowText(handle, builder, length + 1);
        GetWindowRect(handle, out Rect rect);

        windows.Add(new DetectedWindow(handle, rect.ToRect(), builder.ToString()));

        return true;
    }, IntPtr.Zero);

    return windows;
}
Run Code Online (Sandbox Code Playgroud)

熟悉的课程:

public class DetectedWindow
{
    public IntPtr Handle { get; private set; }

    public Rect Bounds { get; private set; }

    public string Name { get; private set; }

    public DetectedWindow(IntPtr handle, Rect bounds, string name)
    {
        Handle = handle;
        Bounds = bounds;
        Name = name;
    }
}
Run Code Online (Sandbox Code Playgroud)

我得到这个应用程序列表(窗口文本 - Rect边界):

Microsoft Visual Studio  - -8;-8;1936;1056
Microsoft Edge - 0;77;1920;963
EnumWindows - Stack Overflow and 7 more pages ?- Microsoft Edge - -8;-8;1936;1056
Microsoft Edge - 0;77;1920;963
Microsoft Edge - 0;77;1920;963
Microsoft Edge - 0;0;1920;1080
Microsoft Edge - 0;0;1920;1080
Microsoft Edge - 0;8;1920;1040
Microsoft Edge - 0;85;1920;963
Microsoft Edge - 150;79;1532;42
Microsoft Edge - 0;85;1920;963
Microsoft Edge - 0;77;1920;963
Microsoft Edge - 0;85;1920;963
Microsoft Edge - 0;213;1920;964
Microsoft Edge - 0;0;1920;1080
Microsoft Edge - 484;208;952;174
Microsoft Edge - 0;84;1920;964
Microsoft Edge - 0;84;1920;964
Microsoft Edge - 0;84;1920;964 
Microsoft Edge - 0;0;1920;1080
Mail - 0;32;1356;693
Mail - 278;252;1372;733
OneNote - 0;8;1920;1040
My notes - OneNote - -8;-8;1936;1056
Photos - 0;32;1920;1008
Photos - -8;-8;1936;1056
Skype - 0;40;1920;1008
Skype - -8;-8;1936;1056
Store - 0;40;1920;1008
Store - -8;-8;1936;1056
Movies & TV - 0;0;1920;1080
Movies & TV - -8;-8;1936;1056
Groove Music - 0;32;1466;712
Groove Music - -7;3;1372;733
Settings - 0;40;1920;1008
Settings - -8;-8;1936;1056
Windows Shell Experience Host - 0;0;1920;1080
Run Code Online (Sandbox Code Playgroud)

我当前最小化的窗口是Visual Studio和两个Edge窗口(每个窗口都有几个选项卡).我可以理解只有一个Edge项目列出了当前页面的标题.因为我最近从崩溃中恢复,只加载了该页面.

我的问题是:

  1. 为什么我的关闭 Windows应用商店应用会被列出?(甚至两次)
  2. 为什么列出我的Edge选项卡?
  3. 如何过滤Edge选项卡和已关闭的 Windows应用商店应用?

编辑:

  1. 通过"过滤器":仅检索具有可见窗口的应用程序.使用我的用例,只能看到3个窗口.

我试图让每个窗口的WsStyle和WsEXStyle进行比较,但我找不到任何区别.

该方法IsWindowVisible()无法过滤掉不可见的Windows应用商店应用.

Han*_*ant 10

为什么我的关闭Windows应用商店应用会被列出?

因为它们实际上并未关闭.使用任务管理器,进程选项卡轻松查看.您将看到拥有这些窗口的进程已暂停.作为WinRT(又名UWP,又称Store,又名现代UI,又名Metro)编程框架方法的一部分,现代机器具有足够的RAM,使得即使用户不与它们交互也能保持进程运行.再次快速将它们带回来并节省电池寿命.如果在其他地方需要RAM,那么操作系统将通过杀死这样的过程来挽救它.

为什么列出我的Edge选项卡?

因为Edge也是一个WinRT应用程序.

如何过滤Edge选项卡和已关闭的Windows应用商店应用?

由于窗口实际上未关闭,因此您想要过滤哪个属性并不完全清楚.GetWindowThreadProcessId()和IsImmersiveProcess()可以告诉您正在处理这样的过程.考虑IsWindowVisible().也许这篇文章可以帮助,也告诉你为什么你看到多个窗口.


编辑(Nicke Manarin):

通过检查Cloacked属性,可以忽略隐藏/后台Store应用程序:

DwmGetWindowAttribute(handle, (int)DwmWindowAttribute.Cloaked, out bool isCloacked, Marshal.SizeOf(typeof(bool)));

if (isCloacked)
    return true;
Run Code Online (Sandbox Code Playgroud)

编辑2(Nicke Manarin):

每个Edge选项卡的行为都像一个窗口(我相信它与您可以拖动选项卡以创建新窗口这一事实有关).

  • 隐藏窗口从IsWindowVisible()返回TRUE,但实际上不可见.不幸. (2认同)