当新窗口添加到桌面时,是否会触发任何事件?

3
我想知道当桌面上出现/打开一个新窗口时是否会触发任何事件。我可以使用COM、WMI、WinApis、UIAutomation或任何其他方法,但首选语言是C#。
实际需求: 一个进程有1个主窗口和许多其他窗口。其中一个窗口的类名为X(我使用pinvoke获取了此信息)。现在,每当进程中有通知时,该窗口会弹出几次。我不想显示这个窗口。我没有代码访问权限,因此无法禁用该窗口。那么,是否有任何方式可以获得事件或任何其他机制,以跟踪桌面,并在任何时候隐藏具有类名X的窗口。
如果我的问题不清楚,请告诉我。 谢谢。
编辑:Simon的答案非常好。我尝试了一下,能够收到除Lync的IM toast通知或Outlook新邮件通知等通知/Toast窗口之外的所有窗口的通知。我尝试了UIAUtomation的不同元素和Windows模式,但仍然无法获取它们...有什么想法吗?您可以阅读Simon答案中的评论以获取更多上下文/详细信息。再次感谢Simon介绍UIAUtomation的强大功能...太棒了!

1
我认为你可以使用UI Automation - 它支持WindowOpened事件。 - undefined
3个回答

11

就像达米恩在评论中所说的那样,你可以在一个C#示例控制台应用程序中使用UI自动化,如下所示:

class Program
{
    static void Main(string[] args)
    {
        Automation.AddAutomationEventHandler(WindowPattern.WindowOpenedEvent, AutomationElement.RootElement, TreeScope.Subtree, (sender, e) =>
            {
                AutomationElement src = sender as AutomationElement;
                if (src != null)
                {
                    Console.WriteLine("Class : " + src.Current.ClassName);
                    Console.WriteLine("Title : " + src.Current.Name);
                    Console.WriteLine("Handle: " + src.Current.NativeWindowHandle);
                }
            });

        Console.WriteLine("Press any key to quit...");
        Console.ReadKey(true);
    }
}

嘿...谢谢...我还有一个问题...我们能否获取关于Windows的信息,比如Outlook中收到新邮件时或Lync/Skype中收到新即时消息时弹出的通知?我尝试了上面的代码,但它没有显示这种类型的窗口...通过其他的Windows API,我发现,例如,Lync弹出通知的窗口类与会话窗口类不同。所以我希望在这里获取事件后,只需隐藏那个窗口。 - undefined
Windows的树非常庞大。示例使用AutomationElement.RootElement(即桌面窗口)作为父级,并且它不会获取所有子窗口的通知。但是您可以使用其他元素作为起点。您可以使用AutomationElement.FromHandle、FromPoint等方法获取其他元素。 - undefined
我正在Windows 10上使用.NET自动化库。我按照你的示例添加了一个事件处理程序,根元素为RootElement,范围为Subtree。但奇怪的是,每次打开一个窗口时,我们几乎总是会看到两个事件。偶尔可能只有一个事件,但超过95%的情况下都是两个。这些事件是不同的对象,但包含相同的EventId和来源。有什么线索可以查找吗? - undefined
@SteveRobbins - 今天我已经在Windows 10上测试了我的答案代码,一切正常。你对我的示例或其他代码有问题吗?如果是其他代码的话,你应该提出另一个问题。 - undefined
@SimonMourier 很好的问题。我之前使用的是自己的代码,但今天我按照你上面提供的代码进行了编译。我确实看到了相同的行为 - 但只有少数应用程序(目前为止只有两个)出现了双重打开事件。其中一个是我们公司的应用程序,但另一个是Adobe Acrobat Reader DC版本2020.006.20034。所以这个谜团更加深奥了。 - undefined
显示剩余2条评论

3

一种选择是使用 RegisterShellHookWindow。你提供一个窗口句柄来接收通知消息。可能对你有用的通知是 HSHELL_WINDOWCREATED 或者 HSHELL_WINDOWACTIVATED


0

这里MSDN提供了注册Windows通知的代码。但是这个代码是针对Windows Server 2008的。我认为你可以找到适用于你的Windows版本的类似代码。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接