如何在C#中从Windows10Forms获取按钮句柄?

如何在C#中从Windows10Forms获取按钮句柄?,c#,handle,external-application,C#,Handle,External Application,我一直在尝试在程序中找到某个特定帮助按钮的句柄,然后向其发送BN_CLICK消息。为了调试,我查看了父窗口和按钮的句柄 [DllImport("User32.dll", EntryPoint = "FindWindow")] private static extern IntPtr FindWindow(string lpClassName, string lpWindowName); [DllImport("User32.dll", EntryPoint = "FindWindowEx")]

我一直在尝试在程序中找到某个特定帮助按钮的句柄,然后向其发送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返回一个数字,但为button返回0。我从Spy++那里得到了这些类。

由于同一类的应用程序中有两个“帮助”按钮,这可能会变得复杂。这是一张应用程序窗口的图片,我正试图通过“帮助”按钮获取句柄,我想单击它,并用红色框突出显示

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

IntPtr button = FindWindowEx(hWndParent, IntPtr.Zero, "WindowsForms10.BUTTON.app.0.2c040a7_r9_ad113", "Help");
这也返回了一个0 for按钮,将“Help”替换为null也是如此。如果有人熟悉从Windows 10窗体获取句柄,并且知道如何执行此操作,将非常感谢您的帮助。谢谢


安德鲁

感谢汉斯的帖子——它为我指明了正确的方向。我已经使用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();
//您需要一些资源
使用制度;
使用System.Windows.Forms;
使用OpenQA.Selenium.Appium.Windows;
使用OpenQA.Selenium.Remote;
//让我们的司机
受保护的静态窗口驱动程序;
//我不想手动打开WinAppDriver,所以。。
System.Diagnostics.Process pProcess=新的System.Diagnostics.Process();
pProcess.StartInfo.FileName=@“C:\Program Files(x86)\Windows应用程序驱动程序\WinAppDriver.exe”;
pProcess.StartInfo.Arguments=“olaa”//论点
pProcess.StartInfo.UseShellExecute=false;
pProcess.StartInfo.RedirectStandardOutput=true;
pProcess.StartInfo.WindowsStyle=System.Diagnostics.ProcessWindowsStyle.Hidden;
pProcess.StartInfo.CreateNoWindow=true//不要铺窗户
p进程开始();
字符串输出=pProcess.StandardOutput.ReadToEnd()//输出结果
pProcess.WaitForExit();
//现在我通过设置驱动程序连接到我的应用程序
DesiredCapabilities=新DesiredCapabilities();
caps.SetCapability(“平台名”、“窗口”);
caps.SetCapability(“平台版”、“10”);
caps.SetCapability(“deviceName”、“WindowsPC”);
caps.SetCapability(“app”,“C:\\FileLocation.exe”);
驱动程序=新的Windows驱动程序(新Uri(“http://127.0.0.1:4723"(大写),;
//命令可以按如下方式发送
driver.FindElementByAccessibilityId(“我将在下面解释”)。单击();
为了找到AccessibilityId,我发现最容易使用的工具是。将查找器拖动到所需的按钮上。然后在摘要选项卡中,您的AccessibilityId被简单地标记为“ID”。我选择AccessibilityId是因为我想控制的应用程序中有多个同名按钮


您需要安装并将正确的位置放入代码中。Appium和Selenium可以通过Nuget管理器添加,但我的代码中使用的一些函数已经被去除。我刚刚使用了Selenium.WebDriver和Selenium.Support的3.0.1版本以及Appium.WebDriver的3.0.0.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();
//您需要一些资源
使用制度;
使用System.Windows.Forms;
使用OpenQA.Selenium.Appium.Windows;
使用OpenQA.Selenium.Remote;
//让我们的司机
受保护的静态窗口驱动程序;
//我不想手动打开WinAppDriver,所以。。
System.Diagnostics.Process pProcess=新的System.Diagnostics.Process();
pProcess.StartInfo.FileName=@“C:\Program Files(x86)\Windows应用程序驱动程序\WinAppDriver.exe”;
pProcess.StartInfo.Arguments=“olaa”//论点
pProcess.StartInfo.UseShellExecute=false;
pProcess.StartInfo.RedirectStandardOutput=true;
pProcess.StartInfo.WindowsStyle=System.Diagnostics.ProcessWindowsStyle.Hidden;
pProcess.StartInfo.CreateNoWindow=true//不要铺窗户
p进程开始();
字符串输出=pProcess.StandardOutput.ReadToEnd()//输出结果
pProcess.WaitForExit();
//现在我通过设置驱动程序连接到我的应用程序
DesiredCapabilities=新DesiredCapabilities();
caps.SetCapability(“平台名”、“窗口”);
caps.SetCapability(“平台版”、“10”);
caps.SetCapability(“deviceName”、“WindowsPC”);
caps.SetCapability(“app”,“C:\\FileLocation.exe”);
驱动程序=新的Windows驱动程序(新Uri(“http://127.0.0.1:4723"(大写),;
//命令可以按如下方式发送
driver.FindElementByAccessibilityId(“我将在下面解释”)。单击();
为了找到AccessibilityId,我发现最容易使用的工具是。将查找器拖动到所需的按钮上。然后在摘要选项卡中,您的AccessibilityId被简单地标记为“ID”。我选择AccessibilityId是因为我想控制的应用程序中有多个同名按钮


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

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