質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.35%
C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

Visual Studio

Microsoft Visual StudioはMicrosoftによる統合開発環境(IDE)です。多種多様なプログラミング言語に対応しています。

UI

UIはUser Interfaceの略であり、人間がコンピュータとやりとりをするためのシステムです。

Q&A

解決済

1回答

4071閲覧

C#、UIAutomationで電卓を操作したい。

mmiko

総合スコア13

C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

Visual Studio

Microsoft Visual StudioはMicrosoftによる統合開発環境(IDE)です。多種多様なプログラミング言語に対応しています。

UI

UIはUser Interfaceの略であり、人間がコンピュータとやりとりをするためのシステムです。

0グッド

0クリップ

投稿2020/05/20 05:52

  • やりたいこと

C#、UIAutomationで電卓を操作したい。

  • 使用しているコード

UIAutomationで.Net製デスクトップアプリのGUIコンポーネントの自動制御を試みるまでのハートフルストーリー
まるまるコピーして実行。

  • 現状

電卓が起動後
mainForm = AutomationElement.FromHandle(process.MainWindowHandle);
にて
>'System.ArgumentException: 'hwnd は IntPtr.Zero または NULL にはできません。'
が発生。

  • 実行環境

VisualStudio2019の「コンソールアプリケーション」のC#プロジェクト
下記は参照追加済み。
UIAutomationClient
UIAutomationTypes

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

Zuishin

2020/05/20 06:00

情報が古いです。当時 Windows 10 はまだなかったので、Windows 10 のものとは電卓が違います。
mmiko

2020/05/20 06:58

ありがとうございます。理解できました。
guest

回答1

0

ベストアンサー

一応これで動きましたがごまかしがあります。

  • 本来NormalOutputが欲しかったがFindAllでとれない(TreeWalkerが必要)のと、Nameに方向制御コードがついていて面倒だったのでCalculatorResultsで^^;
  • 「キーボードからの文字入力」のほうは、SendKeysは使えるがカッコは認識しない

cs

1using System; 2using System.Collections.Generic; 3using System.Diagnostics; 4using System.Linq; 5using System.Threading; 6using System.Windows.Automation; 7 8namespace Questions263202 9{ 10 internal class Program 11 { 12 private static void Main() 13 { 14 var process = Process.Start("calc"); 15 try 16 { 17 Thread.Sleep(1000); 18 19 // UWPだといろいろあるようなので、Processをタイトルから取り直す 20 foreach(var p in Process.GetProcesses()) 21 { 22 if(p.MainWindowTitle.Contains("電卓")) 23 { 24 process = p; 25 break; 26 } 27 } 28 29 var mainForm = AutomationElement.FromHandle(process.MainWindowHandle); 30 var btnClear = FindElementsByName(mainForm, "クリア").First() 31 .GetCurrentPattern(InvokePattern.Pattern) as InvokePattern; 32 btnClear.Invoke(); 33 34 var btn7 = FindButtonsByName(mainForm, "7").First() 35 .GetCurrentPattern(InvokePattern.Pattern) as InvokePattern; 36 37 foreach(var _ in Enumerable.Repeat(0, 7)) 38 { 39 btn7.Invoke(); 40 } 41 42 var resultArea = FindElementById(mainForm, "CalculatorResults"); 43 var EXPECTED_VALUE = "表示は 7,777,777 です"; 44 var actualValue = resultArea.Current.Name; 45 Console.WriteLine("期待値 {0} に対して、結果値は {1} です", EXPECTED_VALUE, actualValue); 46 Console.WriteLine("テスト結果は {0} です", EXPECTED_VALUE == actualValue ? "OK" : "NG"); 47 48 Console.ReadKey(); 49 } 50 finally 51 { 52 process.CloseMainWindow(); 53 } 54 } 55 56 private static AutomationElement FindElementById(AutomationElement rootElement, string automationId) 57 => rootElement.FindFirst(TreeScope.Element | TreeScope.Descendants, new PropertyCondition(AutomationElement.AutomationIdProperty, automationId)); 58 59 private static IEnumerable<AutomationElement> FindElementsByName(AutomationElement rootElement, string name) 60 => rootElement.FindAll(TreeScope.Element | TreeScope.Descendants, new PropertyCondition(AutomationElement.NameProperty, name)).Cast<AutomationElement>(); 61 62 private static IEnumerable<AutomationElement> FindButtonsByName(AutomationElement rootElement, string name) 63 => FindElementsByName(rootElement, name).Where(x => x.Current.ClassName == "Button"); 64 } 65}

投稿2020/05/20 10:10

編集2023/07/21 14:07
TN8001

総合スコア9862

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.35%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問