Fragrammer’s Blog

破片プログラマーから脱する

途中経過

メモ帳での保存時のダイアログの扱いで苦戦中。
AutomationElement.FocusedElementでフォーカスされたダイアログのAutomationElement を取得しようとするも、例外発生して終了。
・AutomationElementの取得有無未確認
・ダイアログや子Windowの扱いについて、まだ未整理

using System;
using System.Collections.Generic;
using System.Linq;
using System.Diagnostics;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Automation;
using System.Windows.Forms;

namespace UIAutoPractice
{
    class Program
    {
        private static readonly string PROCESS_NAME = @"notepad";
        private static readonly int DEFAULT_WAIT_TIME = 1000;

        private static AutomationElement mainForm;
        static void Main(string[] args)
        {

            Process process = Process.Start(PROCESS_NAME);
            try
            {
                // メモ帳を起動します
                Thread.Sleep(DEFAULT_WAIT_TIME);
                mainForm = AutomationElement.FromHandle(process.MainWindowHandle);
                // あああああ
                string InputText = "あああああ";
                // 入力準備
                object valuePattern = null;
                if (!mainForm.TryGetCurrentPattern(ValuePattern.Pattern, out valuePattern))
                {
                    mainForm.SetFocus();
                    Thread.Sleep(100);
                    SendKeys.SendWait(InputText);
                }
                else
                {
                    mainForm.SetFocus();
                    ((ValuePattern)valuePattern).SetValue(InputText);
                }
                // 閉じる
                if (!mainForm.TryGetCurrentPattern(WindowPattern.Pattern, out valuePattern))
                {
                    //mainForm.SetFocus();
                    //Thread.Sleep(100);
                    //SendKeys.SendWait(InputText);
                }
                else
                {
                    mainForm.SetFocus();
                    ((WindowPattern)valuePattern).Close();
                }

                // 保存するかどうか聞かれた時のダイアログを取得
                AutomationElement subForm = AutomationElement.FocusedElement;
                // 保存ボタン取得
                var btn = FindButtonsByName(subForm, "キャンセル").First().GetCurrentPattern(InvokePattern.Pattern) as InvokePattern;
                // 保存実行
                btn.Invoke();
            
            }
            finally
            {
                process.CloseMainWindow();
            }
        }

        // 指定したID属性に一致するAutomationElementを返します
        private static AutomationElement FindElementById(AutomationElement rootElement, string automationId)
        {
            return rootElement.FindFirst(
                TreeScope.Element | TreeScope.Descendants,
                new PropertyCondition(AutomationElement.AutomationIdProperty, automationId));
        }

        // 指定したName属性に一致するAutomationElementをすべて返します
        private static IEnumerable<AutomationElement> FindElementsByName(AutomationElement rootElement, string name)
        {
            return rootElement.FindAll(
                TreeScope.Element | TreeScope.Descendants,
                new PropertyCondition(AutomationElement.NameProperty, name))
                .Cast<AutomationElement>();
        }

        // 指定したName属性に一致するボタン要素をすべて返します
        private static IEnumerable<AutomationElement> FindButtonsByName(AutomationElement rootElement, string name)
        {
            const string BUTTON_CLASS_NAME = "Button";
            return from x in FindElementsByName(rootElement, name)
                   where x.Current.ClassName == BUTTON_CLASS_NAME
                   select x;
        }

    }
}