【问题标题】:How do I get a button handle from Windows10Forms in C#?如何从 C# 中的 Windows10Forms 获取按钮句柄?
【发布时间】:2020-04-07 08:35:30
【问题描述】:

我一直试图在程序中找到特定帮助按钮的句柄,然后向它发送 BN_CLICK 消息。为了调试,我查看了父窗口和按钮的句柄。

[DllImport("User32.dll", EntryPoint = "FindWindow")]
private static extern IntPtr FindWindow(string lpClassName, string lpWindowName);

[DllImport("User32.dll", EntryPoint = "FindWindowEx")]
private static extern IntPtr FindWindowEx(IntPtr parentHandle, IntPtr childAfter, string lclassName, string windowTitle);

public Form1()
{
   IntPtr hWndParent = FindWindow("WindowsForms10.Window.8.app.0.2c040a7_r9_ad1", null);
   Debug.WriteLine(hWndParent,"\n");
   IntPtr button = FindWindowEx(hWndParent, IntPtr.Zero, "WindowsForms10.BUTTON.app.0.2c040a7_r9_ad1", "Help");
   Debug.WriteLine(button);
}

调试为 hWndParent 返回一个数字,但为按钮返回 0。我从 Spy++ 获得了课程。 1

这可能会因为应用程序中有两个具有相同类的“帮助”按钮而变得复杂。这是我正在尝试使用帮助按钮获取句柄的应用程序窗口的图片,我想单击以红色框突出显示。2

我尝试添加通过 AutoIT Info 获得的实例编号。

IntPtr button = FindWindowEx(hWndParent, IntPtr.Zero, "WindowsForms10.BUTTON.app.0.2c040a7_r9_ad113", "Help");

这也为按钮返回了 0,将“帮助”替换为 null 也是如此。如果有人熟悉从 Windows 10 窗体获取句柄并且知道如何执行此操作,我们将不胜感激。谢谢!

安德鲁

【问题讨论】:

  • 类名是自动生成的,并且在运行之间不一致。所以这对你没有任何帮助,请改用 UI 自动化。
  • @Andrew - 我认为Link 会帮助你

标签: c# handle external-application


【解决方案1】:

感谢 Hans 的帖子 - 它为我指明了正确的方向。我已经使用 Selenium 和 Appium 来自动化点击/输入。对于将来在寻找解决方案时偶然发现此问题的任何人,这里有一些代码可以提供帮助。

// You will need a few resources

using System;
using System.Windows.Forms;
using OpenQA.Selenium.Appium.Windows;
using OpenQA.Selenium.Remote;

// Making our driver

protected static WindowsDriver<WindowsElement> driver;

// I don't want to have to manually open WinAppDriver so..

System.Diagnostics.Process pProcess = new System.Diagnostics.Process();
pProcess.StartInfo.FileName = @"C:\Program Files (x86)\Windows Application Driver\WinAppDriver.exe";
pProcess.StartInfo.Arguments = "olaa"; //argument
pProcess.StartInfo.UseShellExecute = false;
pProcess.StartInfo.RedirectStandardOutput = true;
pProcess.StartInfo.WindowStyle = System.Diagnostics.ProcessWindowStyle.Hidden;
pProcess.StartInfo.CreateNoWindow = true; //not diplay a windows
pProcess.Start();
string output = pProcess.StandardOutput.ReadToEnd(); //The output result
pProcess.WaitForExit();

// Now I connect to my app by setting up the driver

DesiredCapabilities caps = new DesiredCapabilities();
caps.SetCapability("platformName", "Windows");
caps.SetCapability("platformVersion", "10");
caps.SetCapability("deviceName", "WindowsPC");
caps.SetCapability("app", "C:\\FileLocation.exe");
driver = new WindowsDriver<WindowsElement>(new Uri("http://127.0.0.1:4723"), caps);

// Commands can be sent as below

driver.FindElementByAccessibilityId("I'll explain this below").Click();

要查找 AccessibilityId,我发现最容易使用的工具是 AutoIT Window Info。将查找器拖到所需的按钮上。然后在摘要选项卡中,您的 AccessibilityId 被简单地标记为“ID”。我选择了 AccessibilityId,因为我想控制的应用程序中有多个同名按钮。

您需要安装WinAppDriver 并将正确的位置放入代码中。 Appium 和 Selenium 可以通过 Nuget Manager 添加,但我的代码中使用的一些函数已被弃用。我刚刚使用了 3.0.1 版本的 Selenium.WebDriver 和 Selenium.Support 以及 3.0.0.1 版本的 Appium.WebDriver(其他版本可能有效,这些只是第一个有效的版本)。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-09-11
    • 2014-05-22
    • 1970-01-01
    • 2010-10-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多