なんか自動でクリックとかする感じのを試してみた。
ほぼコパイロットくんが言ってきた内容そのままです
操作される方のプログラム
WPFアプリでこんな感じのプログラムを作って起動しておく。(App.xamlは略)
MainWindow.xaml
<Window x:Class="WpfApp1.MainWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" Title="MainWindow" Height="350" Width="525"> <Grid Name="MainGrid"> <Button Content="クリック" Width="100" Height="30" HorizontalAlignment="Center" VerticalAlignment="Center" Click="Button_Click"/> </Grid> </Window>
MainWindow.xaml.cs
using System.Windows; using System.Windows.Controls; namespace WpfApp1 { public partial class MainWindow : Window { public MainWindow() { InitializeComponent(); Button button = new Button { Content = "クリック", Width = 100, Height = 30 }; button.Click += Button_Click; MainGrid.Children.Add(button); // Grid に追加 } private void Button_Click(object sender, RoutedEventArgs e) { MessageBox.Show("ボタンが押されました!"); } } }
操作する方のプログラム
別のプロジェクトで、コンソールアプリ(.NET Framework)を作成。
プロジェクト以下の「参照」→「参照の追加」で参照マネージャを開き、左枠アセンブリからUIAutomationのClient/Provider/Typesにチェックを入れてOK。
以下のソースをビルドして実行すると、先に起動したプログラムにアタッチ?してボタンを押してくれる。
Program.cs
using System; using System.Windows.Automation; using System.Threading; class Program { static void Main() { // 1. ターゲットとなるウィンドウのタイトル(MainWindow と一致) string windowTitle = "MainWindow"; // 2. 対象のウィンドウを探す AutomationElement mainWindow = null; for (int i = 0; i < 10; i++) { mainWindow = AutomationElement.RootElement.FindFirst( TreeScope.Children, new PropertyCondition(AutomationElement.NameProperty, windowTitle) ); if (mainWindow != null) break; Thread.Sleep(500); // 起動待ち } if (mainWindow == null) { Console.WriteLine("ウィンドウが見つかりませんでした。"); return; } Console.WriteLine("ウィンドウが見つかりました。"); // 3. "クリック" ボタンを探す(NameProperty を使用) AutomationElement button = mainWindow.FindFirst( TreeScope.Descendants, new PropertyCondition(AutomationElement.NameProperty, "クリック") ); if (button == null) { Console.WriteLine("ボタンが見つかりませんでした。"); return; } Console.WriteLine("ボタンが見つかりました。クリックを試みます..."); // 4. Invoke パターンでクリック if (button.TryGetCurrentPattern(InvokePattern.Pattern, out object pattern)) { ((InvokePattern)pattern).Invoke(); Console.WriteLine("ボタンをクリックしました!"); } else { Console.WriteLine("ボタンはクリックできません(InvokePattern 不対応)"); } } }
なんか.NET Frameworkを使わないとAutoXXのdllのメソッド参照に失敗して例外出したりして、これだけ動かすので結構時間が掛かった。Windowsの環境構築は苦手。