SE_BOKUのまとめノート的ブログ

SE_BOKUが知ってること・勉強したこと・考えたことetc

PythonでWindowsアプリを操作する(3):WinMergeを動かす/RPAサンプル

f:id:arakan_no_boku:20190817094431p:plain

 目次

今回動かしてみるのは、「WinMerge

ファイル・フォルダを複数指定して、内容を比較して、差分をグラフィカルに表示してくれるソフトです。

自動化する操作はざっくしこんな感じです。

まず、起動します。

起動したらファイル>開くでダイアログを開きます。

f:id:arakan_no_boku:20190825221000p:plain

ファイル選択ダイアログで、1stと2ndに比較するファイルを入力します。

今回は「参照」ボタンで開くダイアログをだして、指定のファイルを選択して開くというのを、2回繰り返します。

f:id:arakan_no_boku:20190825221333p:plain

2回繰り返した結果がこんな感じ。

f:id:arakan_no_boku:20190825221428p:plain

これでOKボタンを押します。

今回は、両方に同じファイルを選択しているので、差異がないと表示されます。

f:id:arakan_no_boku:20190825221553p:plain

ここまでを自動化してやってみようというわけです。

雰囲気的に「オートメーションっぽい・・」感じはしますね。 

 

WInMergeを自動実行するpythonソース

 ソースコードはこんな感じ。

import unittest
from appium import webdriver


class SampleTests(unittest.TestCase):

    def setUp(self):
        # set up appium
        desired_caps = {}
        # WinMergeを起動
        desired_caps["app"] = 'C:/Program Files/WinMerge/WinMergeU.exe'
        self.driver = webdriver.Remote(
            command_executor='http://127.0.0.1:4723',
            desired_capabilities=desired_caps)

    def tearDown(self):
        # self.driver.quit()
        # 結果画面を確認するためdriverを強制終了しないようにしている
        print("tear down")

    def test_input(self):
        # ファイル>開くのメニューを選択する
        self.driver.find_element_by_name("ファイル(F)").click()
        self.driver.find_element_by_accessibility_id("57601").click()
        # 1stの参照ボタンを押す
        self.driver.find_element_by_accessibility_id('1001').click()
        # 指定ファイルを選択して「開く」ボタンを押す
        self.driver.find_element_by_class_name(
            'UIItemsView').find_element_by_name(
            '20160603_juyo1_kansai.csv').click()
        self.driver.find_element_by_accessibility_id('1').click()
        # 2ndの参照ボタンを押す
        self.driver.find_element_by_accessibility_id('1002').click()
        # 指定ファイルを選択して「開く」ボタンを押す
        self.driver.find_element_by_class_name(
            'UIItemsView').find_element_by_name(
            '20160603_juyo1_kansai.csv').click()
        self.driver.find_element_by_accessibility_id('1').click()
        # OKボタンを押す
        self.driver.find_element_by_name("OK").click()
        # 強制的にOKにしておく
        self.assertTrue(1)


if __name__ == '__main__':
    suite = unittest.TestLoader().loadTestsFromTestCase(SampleTests)
    unittest.TextTestRunner(verbosity=2).run(suite)

なお、各パラメータの値は自分の環境で「inspect.exe」で調べた値です。

たぶん大丈夫と思いますが、環境によって変わる(特に数字の部分)可能性はゼロではないので、一応お断りをいれておきます。

以下、ポイントを補足していきます。 

ポイント1:画面入力時入力できない文字など 

本当は、片方は「参照」ボタンにして、片方はWindowsのPathをダイレクトにテキストボックスにsend_keysで入力しようとしました。

f:id:arakan_no_boku:20190825225504p:plain

ところがsend_keysでは、pathがうまく入力できないのです。

まず。

"\" がうまく入力できません。

エラーになったり、"]"に変換されてしまったりします。

なので、c:/xxxx/xxxxx/csv のように"/"(スラッシュ)で指定するように変更してみました。

WinMergeはそれでもいけますから。

そしたら、今度は":"(コロン)が通りません。

残念ながら、回避する方法が現時点ではわかりません。

ということで・・。

両方共参照ボタンを押して選択する方法を選ばざるをえなかった・・という訳です。 

ポイント2:ネストする画面パーツ(エレメント) 

参照ボタンで開くダイアログを開いて、ファイルを選択する部分です。

inspect.exeで確認すると「Name」がファイル名になっているので、単純に以下のようにやってみたところ、エラーになりました。

find_element_by_name( '20160603_juyo1_kansai.csv')

inspect.exeで再確認してみると。

f:id:arakan_no_boku:20190825231709p:plain

どうも「項目ビュー一覧」というビューがあって、その下にファイル名のビューが並んでいるみたいです。

だから、以下のようにネストした形でエレメントを取得しています。

self.driver.find_element_by_class_name( 'UIItemsView').find_element_by_name( '20160603_juyo1_kansai.csv').click()

 UIItemsViewは、項目一覧ビューの「ClassName」です。

これでいけました。 

いくつか試してみた感想

WinAppDriverを使って、WindowsアプリケーションをPythonで動かすのは、現時点ではSeleniumでWebアプリを動かすのと似て非なるものだと感じます。

Seleniumライクなんですけど、Seleniumの感覚で単純にできるわけではありません。

それに。

Driverを動かすのに、都度都度開発者モードに切り替えるのは、ちょっと面倒です。

とはいえ。

WindowsアプリケーションをPythonでコントロールするのは、単純に面白いです。

仕事で使う提案は、現時点では、しづらい・・というかできないと、個人的には感じてしまいましたけど。

今回はこんなところで。

ではでは。

 

第一回目と第二回目のリンク

 arakan-pgm-ai.hatenablog.com

arakan-pgm-ai.hatenablog.com