【问题标题】:How do I find the window handle for a running process?如何找到正在运行的进程的窗口句柄?
【发布时间】:2011-01-20 16:45:56
【问题描述】:

我正在尝试从进程中获取窗口句柄。现在,该进程显示一个启动画面,因此,如果我尝试 ProcessInstance.MainWindowHandle,我得到的只是该进程主窗口的句柄,即启动画面。

如何找到我想要的窗口?也许如果我能得到一个进程的窗口列表,我可以选择我想要的。

这是我正在尝试的代码:

AutomationElement aeProcessInstance =
  AutomationElement.FromHandle(mProcess.MainWindowHandle);

AutomationElement aeButton = aeProcessInstance.FindFirst(
  TreeScope.Descendants,
  new PropertyCondition(AutomationElement.NameProperty, "Start"));

aeButton.SetFocus();
Thread.Sleep(1000);
SendKeys.SendWait("{ENTER}");

【问题讨论】:

标签: c# .net process window


【解决方案1】:

这是一项具有挑战性的任务。一个应用程序可以有任意数量的顶级窗口。这些可以在应用程序运行时来来去去。

我看到您正在使用 SendKeys - 您是在编写自动化系统还是测试系统?如果是这样,您可能需要查看 this question 的已接受答案。

您能更好地解释一下您要做什么吗?例如,您是否正在使用随机应用程序?还是您可以控制目标流程?

更新

好的,您的额外信息意味着这个问题更容易处理。您需要使用Spy++、调试器或XperfProcess Explorer 或其他一些工具来理解窗口和线程行为。

一旦你知道了,你就可以使用各种Window management functions来找到你需要的窗口并处理它。

另外,请注意Windows Integrity Mechanism。用于在另一个进程中查找窗口并向其发送消息的应用程序必须具有比驱动应用程序更高的完整性级别 (IL)。

【讨论】:

  • 我不使用随机应用程序,它是一个特定应用程序,并且控制逻辑是针对该特定应用程序“硬编码”的。但是,它不是我的应用程序,所以我无法控制它(控制我的意思是源代码)。我正在编写一个自动化程序,基本上它的作用是检查进程是否正在运行,如果它正在运行单击按钮开始在其中...如果它没有运行或没有响应重新启动它。它适用于有时会崩溃的网络服务器之类的应用程序,我需要找到一种方法(阅读:hack)来强制它实际工作 xD
  • 实际上,我想使用 C#,因为我计划添加更多功能,但我不想学习 AutoIt 或其他东西,因为我找不到枚举窗口的方法进程:/
【解决方案2】:

如果你知道进程中UI线程的ID,你可以通过pinvokingEnumThreadWindows找出该线程拥有哪些窗口

EnumThreadWindows 函数枚举与线程关联的所有非子窗口,方法是将每个窗口的句柄依次传递给应用程序定义的回调函数。 EnumThreadWindows 一直持续到枚举最后一个窗口或回调函数返回 FALSE。要枚举特定窗口的子窗口,请使用 EnumChildWindows 函数。

如果应用程序没有显示任何对话框,这应该为您提供它的顶级窗口。如果它有对话框,您将不得不使用窗口的属性来确定哪个是应用程序窗口。窗口样式通常适用于此。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-12-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多