UiAutomation

Windows��Python��uiautomation���g���@�����܂����̂� ���X�̎�����Y�^�Ƃ��Ă܂Ƃ߂Ă����܂��B �l�b�g�T�[�`�ł͈ӊO�Ɓu�����Ă݂܂����v�I�Ȃ��̂����Ȃ����p�I�Ɏg���̂ɂ͋�J���܂����̂� ���ɗ��Ă�΂Ǝv���܂��B

uiautomation���g���O�ɁA"�{����GUI�c�[���𑀍삷��K�v���L��܂���?"�Ƃ������Ƃ�������x�l���Ă��������B

�V�X�e������͂��������A�v���O������CUI(�R�}���h�x�[�X)�œ������̂����ʂŁA �t�B���^�v���O���~���O��CSV���v���O�����ɐH�킹�ď��������邱�Ƃ��嗬�ł����B �������A�l�Ԃ����삷��ɂ�GUI�̕��������I�Ől�ɗD�����A�Ƃ�������GUI�S���̎���ƂȂ�܂����B ������A�l�Ԃ̕ς���uiautomation�����g����RPA(Robotic Process Automation)�ł�낤�Ƃ��������ɂȂ��Ă��܂��B

�l��GUI�v���O����(����) ���� �������v���O������GUI�v���O����(����)�Ƃ����\���̕ω��ł��B ���̏ꍇ�A�킴�킴GUI���g�p���ē������͖̂��ʂȎ�Ԃł��B ���������ꍇ�ɂ�API�𗘗p�ł��Ȃ����A���[�J���̃V�X�e�����ł�API�ł��ǂ����AWeb-API�ł��ǂ��̂� ��肽�����ւ�API��p�ӂł��Ȃ����l���Ă݂Ă��������B �܂��A�V�X�e���ɃR�}���h���C���ł̃c�[�������������ׂĂ݂�̂��L���ł��B ��������Ζ��ʂȓ����������邱�ƂȂ��v���O���������肽�����������s�ł��܂��B �t�B���^�v���O���~���O�̂悤�ɏ����̃p�[�c����荞��ŁA�A�g�����Ă�肽������������������� ���Ȃ������ŃL�r�L�r�����Ǝv���܂��B

RPA�n�̎������̏ꍇ�A�l�Ԃ̖ڂ�ʂ��Ȃ����Ƃɂ��f�[�^�͈̔͂�l�̌���́A �����Ȋ����ԈႢ��X�y���ԈႢ�ł̑��d�o�^�A ���X�A�l�ԂȂ�A����?�ƋC�t�����ƂɑΉ��ł���̂��̒��ӂ��K�v�ł��B

GUI����̗ǂ��_�͉��L�̂悤�Ȃ��Ƃ��l�����܂��B

�l�����f�o���₷�������񓙂Ńf�[�^��I�������\�������

���W�X�g����DB���ɋL�^�����f�[�^�͂��̒l������\���Ă���̂�������ɂ����������X�L��܂��B �P�Ȃ鐔�l�������肵�Ē��ڑ��삷��ɂ͉�������ׂ����Y�ނ��ƂɂȂ�܂��B ���̓_�AGUI�ł͐l�������ł���\���ɂȂ��Ă���̂ŊԈႢ�ɂ����Ƃ����܂��B

�ЂƂ‚̑I��/�N���b�N�ŕ��G�ȏ��������s�ł���

GUI�ł̂ЂƂ‚̑I�����������ɔ��f���ꂽ��ADB�̕����̃e�[�u���������������肷��ꍇ���L��܂��B �t�Ɍ����Ɖ�������Ă���̂��������ĂȂ��ƃX�N���v�g���Œ��ڑ��삷��͓̂���Ȃ�܂��B

���̂悤�ȏꍇ�A������GUI�𑀍삷��ق������S�m���ɑ��������ł���ƍl�����܂��B

Web�n�̎������ɂ� �X�N���v�g���� + Selenium ���g���̂��ǂ��Ǝv���܂��B

�����̔O�����߂āA�V�k�S�Ȃ��玩�����ɖ��ʂɖ|�M����Ȃ��ʼn������B

Python��uiautomation�g�p���̒��ӎ���

�g�����ȑO�̖��ŐF�X�ƈ������������_���܂��񋓂��܂��B
2021/1/27���_ windows 10 64bit 2004(20H1)�‹��ł��B

python��uiautomation���W���[����Windows��uiautomation�@�\�� python����g����悤�Ƀ��b�v�������̂ł��B�S�Ă�Windows���̋@�\���g����悤�� ����Ă���킯�ł͗L��܂���B

Python�̃o�[�W����

uiautomation���g���ꍇ�A���̃}�V���ɂ��W�J���邱�Ƃ������Ǝv���܂��B ���̎��APython�̓����Ă��Ȃ��}�V����exe�����ēW�J���邱�ƂɂȂ�܂��� 2021/01/27 ���_��pyinstaller��exe������ꍇ�APython��ver 3.9.x�ł� ���s���ɃG���[���o�ē����܂���ł����B�G���[�����̂����@�ł����A ver 3.8.6�ɗ��Ƃ��Ɩ��Ȃ����s�ł��܂����B �e�탂�W���[���̊֌W���Ǝv���܂����Aver 3.8�n�ɂ��Ă������� ���ɉ��Ȃ��Ă��݂܂��B

Symantec��pyinstaller

pyinstaller���g���ꍇ�ASymantec��virus�΍�\�t�g�������Ă���� exe�������v���O�������}���E�G�A�Ƃ��Č��o����A�폜����܂��B 64bit�łȂ�OK�Ƃ�����񂪂���܂������A64bit�łł��������܂����B


Symantec�������p�̏ꍇ�Apyinstaller�̓Ǝ��r���h�����K�v�Ƃ̏�� �L��܂����̂ŁA�g���C���Ă݂Ă��������B ���͓W�J�悪ESET�ł����̂Ńg���C���Ă��܂���B

���I�ȃv���O�����ɒ���

�ŋ߂̃v���O�����ł�ui�̑ΏۂƂȂ��ʍ\��(=�I�u�W�F�N�g�\��)�� ���I�Ȃ��̂������A�������ꂽ��łȂ���uiautomation�ł͌��o�ł��܂���B


�܂��A��ʂɕ\������Ă��Ȃ����̂̓N���b�N�ł��܂���B ���ׁ̈A�N���b�N����ɂ̓��j���[���ʂ��X�N���[��������A�܂肽���܂�Ă�����̂� �W�J���Ă��瑀�삷��K�v���L��܂��̂Œ��ӂ��K�v�ł��B

�C���X�g�[��

�ʏ�̃��W���[���̃C���X�g�[���Ɠ��l��pip�ŃC���X�g�[���”\�ł��B

uiautomation�ȊO�ɕK�v�ȃ��W���[�����L��Γ��l�ɃC���X�g�[�����ĉ������B

pip install uiautomation

Windows��SDK����inspect�v���O�������C���X�g�[�����Ă����ƁA�I�u�W�F�N�g�̍\���� ���ׂ邱�Ƃ��o���܂��̂ŃC���X�g�[�����邱�Ƃ������߂��܂��B

���p���Ă���Windows��SDK��Microsoft����_�E�����[�h�”\�ł��B "Windows SDK inspect"�ӂ�Ō�������ƃC���X�g�[�����@�����‚���܂��B

�C���X�g�[���e�X�g

��肭�C���X�g�[������Ă��邩���L�̃R�[�h�����s���Ă݂Ă��������B �X�^�[�g�{�^�����������Ƃ��̏�Ԃɐ����OK�ł��B

���{��‹�Windows�����肵�Ă��܂��̂ő��̌���‹�����Name="�X�^�[�g"��ύX����K�v���L��ł��傤�B �\�[�X�̕����R�[�h��UTF-8�ł��B

���̃h�L�������g�̃R�[�h�͈ȉ��̊‹��Ŋm�F���Ă��܂��B

windows7 64bit
Python 3.6.5
uiautomation==2.0.10

���̃h�L�������g���ł͉��L�̂悤��uiautomation���C���|�[�g��ui�ŎQ�Ƃ��܂��B
import uiautomation as ui

import uiautomation as ui
s = ui.ButtonControl(searchDepth=2,Name="�X�^�[�g")
s.GetInvokePattern().Invoke()

�X�^�[�g�{�^���I�u�W�F�N�g�����o�����s(Invoke)�����Ă��܂��B
�^�X�N�o�[�������I�ɉB���ݒ�ɂ���Invoke��Click�ɕς��Ă݂�ƃX�^�[�g���j���[���o�܂���B

import uiautomation as ui
s = ui.ButtonControl(searchDepth=2,Name="�X�^�[�g")
s.Click()

1�b�҂��Ă�����x�N���b�N���邩�A�J�[�\���ʒu���w�肵�Ă���N���b�N����Əo�܂��B

���̕ӂ肪���I�ȓ����ɂ�铮��̈Ⴂ�̗�ł��B �^�X�N�o�[�������I�ɉB���ݒ�ɂ��Ă��Ȃ���΃N���b�N�ł����삵�܂��B �o���邾���N���b�N�͎g�킸invoke�ɂ��������肪���Ȃ��ł��傤�B

import uiautomation as ui
import time
s = ui.ButtonControl(searchDepth=2,Name="�X�^�[�g")
s.Click()
time.sleep(1)
s.Click()
import uiautomation as ui
s = ui.ButtonControl(searchDepth=2,Name="�X�^�[�g")
s.MoveCursorToInnerPos()
s.Click()

���삷��I�u�W�F�N�g�𒲂ׂ�

�܂��͎������������v���O�����̃I�u�W�F�N�g�\���𒲂ׂ邱�Ƃ���n�܂�܂��B inspect���g����Ȃ�N�����Ă�����ui�I�u�W�F�N�g�̍\�����\������܂��B �������A�\���`���͏ȗ����ꂽ�L�q�ƂȂ��Ă�����̂��L��A�g�����𐄑����Ďg���K�v���L��܂��B


�Ȃ��ɂ́A.NET��COM�̎d�g�݂ɏ]���Ă��Ȃ��ăI�u�W�F�N�g�\����inspect�ł͒��ׂ��Ȃ��v���O����������܂��B ���̏ꍇ�ɂ́Apython��uiautomation�ő��삷�邱�Ƃ͓���Ȃ�܂��B �p�[�c�摜�ł̉�ʏ�̏ꏊ��T������@�\�̂��鑼�̃c�[�������g�p����ق����ǂ��ł��傤�B

SDK��inspect���g���Ȃ��ꍇ�ɂ�uiautomation���̂ŃI�u�W�F�N�g�\�����_���v���邱�Ƃ��o���܂��B inspect�Ō�������������肭�\���ł��Ȃ��ꍇ�Ȃǂ͎����Œ��ׂ������m����������܂���B ���̃h�L�������g�ł͒����p�̊֐��̗��񋟂��܂��B
���L�̃\�[�X��inspect��python�̃��W���[���ł��BSDK�̂��̂ł͗L��܂���B

�܂��A���L�̓I�u�W�F�N�g�̏���python����̌������ŕ\������v���O�����̗�ł��B
import uiautomation as ui
import inspect

def dump_obj(obj):
    print('----Inspect-----------------------------------------------------')
    if obj == None:
        print('---Obj not exist ----')
    else:
        try:
            print('Obj = ',obj)
            for x in inspect.getmembers(obj):
                print(x[0],':',x[1])
        except Exception as e:
            print(e)

    print('---------------------------------------------------------')

s = ui.ButtonControl(searchDepth=2,Name="�X�^�[�g")
dump_obj(s)

���ɁA�I�u�W�F�N�g�̊K�w��uiautomation�̋@�\�Ń_���v����v���O�����̗�ł��B depth�ʼn����x�����܂ŕ\�����邩���R���g���[���ł��܂��B

�����Ɏg����`���Ń_���v���Ă��܂��̂ł�����R�s�y���ē\��t����΃I�u�W�F�N�g���w��ł��܂��B

import uiautomation as ui

def dump_structure(obj,level,depth=5):
    if obj == None:
        return

    ct=obj.ControlTypeName
    name=obj.Name
    print('{level}:{margin}{ct}(Name="{name}")'.format(level=level,margin='    '*level,ct=ct,name=name))
    if level < depth:
        objs = obj.GetChildren()
        for x in objs:
            dump_structure(x,level+1,depth)

w = ui.WindowControl()
while(w):
    dump_structure(w,1,2)
    w = w.GetNextSiblingControl()

�v���O�����E�C���h�E��I�u�W�F�N�g�̕��т�㉺�֌W�͑I���̏󋵂œ��I�ɕς��܂��B ���Ԗڂ̃I�u�W�F�N�g�Ƃ����w����@�͊댯���Ǝv���܂��B

�v���O�����E�C���h�E�͑I�����ꂽ�v���O��������ɂ���悤�ł��B Windows�̉�ʊǗ���OS�̍���̎��_�ōl����ƁA��ʏ�̃I�u�W�F�N�g��z�I�[�_�[��(��ʏ�̏d�Ȃ�̏�)�� ����ł���Ƒz���ł��܂��B��ʒ��̈ʒu���ォ�珇�ɒ��ׂĂ����ΊȒP�ɑΏۂ̃E�C���h�E�� �R���g���[����T�����Ƃ��ł���悤�ɂ��Ă���Ƒz���ł��܂��B

����������ƑI�����ꂽ�E�C���h�E��|�b�v�A�b�v���ŕ\���������̂́A�㑤�ɍ���܂��B

�^�X�N�o�[����ԏ��PaneControl�ŁA��ԉ��Ƀf�X�N�g�b�v��PaneControl(Name="Program Manager")���L�� ���̊ԂɋN�����ꂽ�v���O�����ނ��d�Ȃ菇�ɔz�u����Ă���悤�ł��B �^�X�N�o�[�͕\�����}�E�X�J�[�\���̈ʒu�ʼnB������\���������肷��K�v���L��̂ň�ԏ�Ȃ�ł��傤�B

���L�̂悤�ɂ���ƑS�̂̍\�����\���ł��܂��B

w = ui.GetRootControl()
dump_structure(w,1,3)

uiautomation�̋@�\�𒲂ׂ�

python�̃C���X�g�[���f�B���N�g��\Lib\site-packages\uiautomation �̉��Ƀ\�[�X������܂��B

�܂�python�̃C���X�g�[���f�B���N�g���̉���uiautomation��doxygen�ɂ����� �h�L�������g ���쐬���܂��B doxygen�̎g�����ɂ‚��Ă͌������Ă��������B �I�v�V�����̒��ӓ_�͉��L�ł��B

Wizard/Mode extraction mode : All Entries
Wizard/Mode language        : Optimize for Java or C# output
Wizard/Output               : HTML�����ŗǂ��Ǝv���܂��B
                            : with navigation panel��with search function �Ƀ`�F�b�N�����܂��B

��Ɨp�ɕʃf�B���N�g�����쐬���A�����Ƀ\�[�X���R�s�[���č�Ƃ���̂����S���Ǝv���܂��B

Microsoft��API��python��uiautomation���W���[�����Ăяo���Ă��܂��B python����g����̂͂���uiautomation���W���[���Œ�`���ꂽ���̂ƂȂ�܂��B

Microsoft�̏��͂��̕ӂ�ł��B
https://docs.microsoft.com/ja-jp/dotnet/framework/ui-automation/ui-automation-fundamentals
https://docs.microsoft.com/en-us/windows/desktop/api/uiautomationclient

doxygen��run������� uiautomation �h�L�������g ���쐬����܂��̂ŕK�v�ɉ����ĎQ�Ƃ��Ă��������B

�E�C���h�E�v���O�����̊�{�\��

������GUI�v���O�������쐬�������Ƃ��L��l�͕������Ă���Ǝv���܂����A ��������Ƃ̖����l������Ǝv���܂��̂Ōy���������܂��B

GUI�v���O�����͈�Ԃ��ƂƂȂ�V�X�e���E�C���h�E�̉��ɁA �e�v���O�������ЂƂ–��͕����̃E�C���h�E�Ƃ��č쐬����܂��B

�}�E�X�J�[�\���C�x���g��L�[�{�[�h�C�x���g�́A�܂��V�X�e���Ŏ󂯎���A �V���[�g�J�b�g�Ȃǂ̔�������ꂽ��A�v���O�����ɓn�����ׂ����̂́A �I������Ă���E�C���h�E�ɓn����܂��B

�e�E�B���h�E���ɂ́AGUI�p�[�c���z�u����Ă��āA�C�x���g�����̍\���ɉ����� �����n����Ă����܂��B

GUI�p�[�c�̓R���g���[��(Control)�ƌĂ΂�Ă��܂��B�Ⴆ�΃{�^��(ButtonControl)�A ��������͂���G�f�B�b�g(EditControl)�B�E�C���h�E(WindowControl)���R���g���[���ł��B

�R���g���[���̓I�u�W�F�N�g�̎�ނ�\���܂��B
�R���g���[���͐F�X�ȋ@�\�p�^�[��(Pattern)�������Ă��܂��B

doxygen�ŏo�����h�L�������g��ButtonControl������ƁA �{�^���R���g���[���͓Ǝ���3�‚̋@�\�p�^�[���������Ă��܂��B �܂����N���X����p�������l�X�ȃ����o�[�֐����g���܂��B
uiautomation�ł̑���͎��(�R���g���[��)�I�u�W�F�N�g�����o���A �X�ɃR���g���[���������Ă���@�\(�p�^�[��)�I�u�W�F�N�g�����o���A �p�^�[���I�u�W�F�N�g�̎��‹@�\���Ăяo���Ƃ�������ł��B

uiautomation.ButtonControl
  ExpandCollapsePattern   GetExpandCollapsePattern (self)
  InvokePattern           GetInvokePattern (self)
  TogglePattern           GetTogglePattern (self)
  
���N���X uiautomation.Control

�����ő�؂Ȃ̂̓L�[�C�x���g��}�E�X�C�x���g�̓E�C���h�E�̏d�Ȃ��A Control�̑I�����ꂽ��Ԃœn�����o�H���ς��Ƃ������Ƃł��B ���o�X�g(�ω��ɋ���)�ȃv���O�����ɂ���ɂ͏o���邾���}�E�X�C�x���g�� �L�[�C�x���g���g�킸�Ainvoke��setvalue���̒���Control�ɍ�p������̂� �g���ق����ǂ��ł��傤�B�������AInvokePattern���������Ă��Ȃ�Click���������o���Ȃ� �P�[�X���L��悤�ł��B���̏ꍇ�ɂ�Click�őΉ����邵���Ȃ��悤�ł��B

�Ώۃv���O�����̋N��

����Ώۂ̃v���O�����͒��ڃv���O�������N������̂���肪���Ȃ��ł��傤�B �f�X�N�g�b�v�̃v���O�����A�C�R�����_�u���N���b�N���Ă����s�ł��܂����A �A�C�R���̏�ɑ��̃E�C���h�E���d�Ȃ��Ă���ƁA���̃E�C���h�E���_�u���N���b�N���Ă��܂��܂��B

�N�����ꂽ�v���O�����̓g�b�v(�ŏ��)�ɕ\������܂��B

�N�����@�̗���������v���O�����Ŏ����Ă݂܂��B

import subprocess
proc = subprocess.Popen('cmd /c "notepad.exe"')

uiautomation �ǂ�������1

�������ŐV�K�e�L�X�g�t�@�C�����쐬���ĕۑ�����܂ł̗�������Ă݂܂��B �r���ɍ\���_���v������ł��܂����A�I�u�W�F�N�g�����‚������Ƃ���Ń_���v����� �_���v���ꂽ������Ώۍ��ڂ��R�s�y���Ă��������ō쐬�ł��܂��B �������I�������_���v�����͏������ɂȂ�܂��B

import uiautomation as ui
import inspect
import time
import subprocess

### dump structure ###
def dump_structure(obj,level,depth=5):
    if obj == None:
        return
    ct=obj.ControlTypeName
    name=obj.Name
    print('{level}:{margin}{ct}(Name="{name}")'.format(level=level,margin='    '*level,ct=ct,name=name))
    if level < depth:
        objs = obj.GetChildren()
        for x in objs:
            dump_structure(x,level+1,depth)

proc = subprocess.Popen('cmd /c "notepad.exe"')
#time.sleep(1)
w = ui.WindowControl(Name='���� - ������')
w.EditControl().GetValuePattern().SetValue('abc')
w.MenuBarControl(Name='�A�v���P�[�V����').MenuItemControl(Name='�t�@�C��(F)').Click()
w.MenuItemControl(Name="�������̏I��(X)").Click()
dump_structure(w,0,5)
w.ButtonControl(Name="�ۑ�����(S)").Click()
dump_structure(w,0,5)
s = ui.WindowControl(Name='���� - ������').WindowControl(Name='���O��t���ĕۑ�')
dump_structure(s,0,5)
s.EditControl(Name='�t�@�C����:').GetValuePattern().SetValue('a.txt')
s.ButtonControl(Name="�ۑ�(S)").Click()
dump_structure(s,0,5)
ui.SetGlobalSearchTimeout(1.0)
try:
    s.WindowControl(Name="���O��t���ĕۑ��̊m�F").ButtonControl(Name="�͂�(Y)").Click()
except Exception as e:
    pass
ui.SetGlobalSearchTimeout(10.0)

dump_structure(s,0,5)

uiautomation�̃v���O�����͂��ꂼ��̃I�u�W�F�N�g�̎��‹@�\�����Ԃ�'.'�Ōq���ł����Ηǂ��A ui.xxxControl(Name='yyy')�̗l�Ȍ`�ŃR���g���[����T���܂��̂ŁA �܂��g�b�v���x���̃v���O�����E�C���h�E�ōi��A�K�w�����ɍ~��Ă����ΖړI�̃I�u�W�F�N�g�� ���B�ł��܂��B�K���������ԂɒH��K�v�͖����r���͔�΂��ĖړI�̃R���g���[�����w�肵�Ă� OK�ł��B�������A�����̃R���g���[���ɂ͒��ӂ��Ă��������B���ɒT���Ă����p�X��� �ړI�̃R���g���[�����O�ɓ����R���g���[���œ����̂��̂�����Ƃ����炪�I�΂�܂��B �o�H����ӂɐ���悤�ɓr���̃I�u�W�F�N�g���w�肵�ĖړI�̃R���g���[���܂ł��w�肵�܂��B

�������̃t�@�C�������o���ł͓����̃t�@�C�������ɗL��ꍇ�ɂ͏㏑���̊m�F�_�C�A���O���o�܂����A�o�Ė����Ă�try�ŃG���[�� �����|���Ĕ����Ă��܂��B�^�C���A�E�g���Ԃ��f�t�H���g��10�b�ƒ����̂�SetGlobalSearchTimeout(1.0)�� �^�C���A�E�g���Ԃ�1�b�ɏk�߂Ă��܂��B�O�̂��ߏI�������f�t�H���g��10�b�ɖ߂��Ă����܂��傤�B

���O�̎w��ɂ͐��K�\�����g���܂��B
�{�^���Ȃǂŗǂ����铯���I�u�W�F�N�g�ł���Ԃɂ���ĕ\������Ă��閼�O���ς��ꍇ�Ȃǂ� ���K�\�����g����ƕ֗��ł��B

w = ui.WindowControl(RegexName=r'.*������')  # '������'�ŏI���E�C���h�E�����w��

uiautomation ���1 ���R�}���h��

���1���R�}���h��������Ɖ��L�̂悤�ɂȂ�܂��B
�������������o���̂��{���ɕK�v���A�A�A

>
> echo abc > a.txt
>

���L�̂悤�ȁA�e�L�X�g�n�̏����͊e��X�N���v�g����ŏ�������̂��y���Ǝv���܂��B

* �e�L�X�g�̎�������
* �e�L�X�g�̒u��
* ��`�t�@�C������^�[�Q�b�g�̐���(�R���p�C���A�����o�^)
* CSV�t�@�C����DB��Excel���ɓo�^�܂��͉��H

���1�̉���(�g����p�^�[���𒲂ׂ�)

���i�K�Ƃ��Ă͐l�Ԃ̑���ʂ�ɃN���b�N���邱�Ƃœ������̂�������₷���ł��� �N���b�N�̓}�E�X�̓�����A��ʂ̏d�Ȃ�ɍ��E�����̂�Click()����菜���Ă݂܂��B

�v���O������ui�\�������āA���삵�����R���g���[�����ǂ̂悤�ȃp�^�[���������Ă��邩���� �p�^�[�������o���āA���삵�܂��B����̏ꍇClick��InvokePattern��Invoke�Œu���������܂��B �e�R���g���[����InvokePattern�������Ă��邱�Ƃ͉��L��dump_supported_patterns�֐��̂悤�Ȃ��̂� �쐬����Βm�邱�Ƃ��o���܂��B

import uiautomation as ui
import inspect
import time
import subprocess

def dump_supported_patterns(obj):
    if obj == None:
        return
    print('{ct}(Name="{name}")'.format(ct=obj.ControlTypeName,name=obj.Name))
    for x in ui.PatternIdNames:
        if obj.GetPattern(x):
            print('-->','Get'+ui.PatternIdNames[x]+'()')

proc = subprocess.Popen('cmd /c "notepad.exe"')

w = ui.WindowControl(Name='���� - ������')
w.EditControl().GetValuePattern().SetValue('abc')

dump_supported_patterns(w.MenuBarControl(Name='�A�v���P�[�V����').MenuItemControl(Name='�t�@�C��(F)'))
w.MenuBarControl(Name='�A�v���P�[�V����').MenuItemControl(Name='�t�@�C��(F)').GetInvokePattern().Invoke()

dump_supported_patterns(w.MenuItemControl(Name="�������̏I��(X)"))
w.MenuItemControl(Name="�������̏I��(X)").GetInvokePattern().Invoke()

dump_supported_patterns(w.ButtonControl(Name="�ۑ�����(S)"))
w.ButtonControl(Name="�ۑ�����(S)").GetInvokePattern().Invoke()

s = ui.WindowControl(Name='���� - ������').WindowControl(Name='���O��t���ĕۑ�')

dump_supported_patterns(s.EditControl(Name='�t�@�C����:'))
s.EditControl(Name='�t�@�C����:').GetValuePattern().SetValue('a.txt')

dump_supported_patterns(s.ButtonControl(Name="�ۑ�(S)"))
s.ButtonControl(Name="�ۑ�(S)").GetInvokePattern().Invoke()

ui.SetGlobalSearchTimeout(1.0)
try:
    dump_supported_patterns(s.WindowControl(Name="���O��t���ĕۑ��̊m�F").ButtonControl(Name="�͂�(Y)"))
    s.WindowControl(Name="���O��t���ĕۑ��̊m�F").ButtonControl(Name="�͂�(Y)").GetInvokePattern().Invoke()
except Exception as e:
    pass
ui.SetGlobalSearchTimeout(10.0)

uiautomation.py������ƕ�����܂����A���ꂼ��Python�̎���(id: ���O)�f�[�^�Ƃ��ĉ��L�Ɉꗗ������܂��B

Control�̎�� : ControlTypeNames

Pattern�̎�� : PatternIdNames

Property�̎�� : PropertyIdNames

�p�^�[���͂��̈ꗗ������o����PatternId��GetPattern(id)���Ăяo���� �p�^�[���I�u�W�F�N�g���Ԃ��Ă����炻�̃p�^�[�����������Ă���ƕ�����܂��B ���̃\�[�X�ł�'Get'��t�����`�ŕ\�����A�R�s�y�Ń\�[�X�ɓ\��t���₷�����Ă��܂��B

����!! uiautomation��GetPattern(id)�Ŏ��o����p�^�[���� �K������GetXxxxxPattern()�Ƃ��Ď������Ă��Ȃ��ꍇ������܂��B GetXxxxPattern()�ŃG���[���o���ꍇ�ɂ͂��̂܂܂ł͎g���܂���B �Ⴆ��EditControl���ł́A���̉���ScrollBarControl���g���Ă��������B

python�̃C���X�g�[���f�B���N�g��\Lib\site-packages\uiautomation �̉��Ƀ\�[�X������̂� �����Œlj����邱�Ƃ͉”\�ł��B

���邢�� GetPattern(ui.PatternId.�I�u�W�F�N�g�������Ă���p�^�[����)�Ŏ��o���� �g�����Ƃ��”\�ł��B

��Ƃ��āu�������v��EditControl��ScrollPattern�������Ă��܂���uiautomation�ł� GerScrollPaterrn()�ł̎��o���͎�������Ă��܂���B �ł�EditControl�I�u�W�F�N�g����GetPattern(ui.PatternId.ScrollPattern)�Ŏ��o���Ă��� �g���邱�Ƃ͊m�F���܂����B

�p�^�[���Ɠ��l�Ƀv���p�e�B�����������Ă��邩�͉��L�̂悤�Ȋ֐������Ǝ��o���܂��B ������͎����Ă��Ȃ��v���p�e�B�����o�����Ƃ���Ɨ�O����������̂ŁAtry�Ŋ����Ă��܂��B

def dump_supported_propeties(obj):
    if obj == None:
        return
    print('{ct}(Name="{name}")'.format(ct=obj.ControlTypeName,name=obj.Name))
    for x in ui.PropertyIdNames:
        try:
            v = obj.GetPropertyValue(x)
        except:
            v=None
        if v:
            print('...',ui.PropertyIdNames[x],'=',v)

����łق�UI�̑���ɕK�v�ȓ���Ă͑����܂����B ��͊e�p�^�[���̎��‹@�\�𒲂ׂ鎖�ɂȂ�܂��B

May the source be with you.
uiautomation�̃h�L�������g ���Q�Ƃ��Ȃ���\�[�X������̂���Ԋm���ł��B

�����ŏЉ���֐��̃\�[�X��u���Ēu���܂��B

�悭�g�������ȋ@�\

�E�C���h�E�̑��쓙�ŗǂ��g�������ȋ@�\���܂Ƃ߂Ēu���܂��B

Click()�𖳂���

�N���b�N���g�킸�ɓ��������Ɏg���@�\

GetInvokePattern().Invoke()
InvokePattern�������Ă���΂���ŃN���b�N�̑���ɂȂ�܂��B

obj.GetInvokePattern().Invoke()

GetSelectionItemPattern().Select()
���j���[�⃊�X�g����SelectionItemPattern�������Ă���΂���őI���ł��܂��B SelectionItemPattern���h�L�������g�Œ��ׂ��IsSelected()���L�� �I������Ă��邩�����ׂ��܂��B

obj.GetSelectionItemPattern().Select()

GetWindowPattern().Close()
SetWindowVisualState(ui.WindowVisualState.Maximized)
�E�C���h�E�̃N���[�Y�A�ő剻�A�ŏ�������WindowPattern�̊֐��Ăяo���łł��܂��B WindowVisualState�N���X�� Normal = 0�AMaximized = 1�AMinimized = 2 �ƒ�`����Ă��܂��B

proc = subprocess.Popen('cmd /c "notepad.exe"')
w = ui.WindowControl(Name='���� - ������')
p = w.GetWindowPattern()
p.SetWindowVisualState(ui.WindowVisualState.Maximized) # �E�C���h�E�̍ő剻
time.sleep(2)
p.Close()

��ʂɌ�����悤�ɂ���

GetScrollItemPattern().ScrollIntoView()
ScrollItemPattern �������Ă���� ScrollIntoView�Ŏ����I�ɃX�N���[�����Č�����悤�ɂ��Ă���܂��B

obj.GetScrollItemPattern().ScrollIntoView()

�C���X�g�[������uiautomation�ł�Button���ɂ��̋@�\���C���v�������g����Ă��܂���B �����鏊�Ɉړ��������I�u�W�F�N�g������΁A inspect��IsScrollItemPatternAvailable��true�ł���Ύg���܂��̂ŁA�C���X�g�[�������\�[�X�� uiautomation.py��������ListItemControl�̒���GetScrollItemPattern�̕����� �K�v�ȃR���g���[���̉��ɃR�s�[����Ǝg����悤�ɂȂ�܂��B

�����ŃX�N���[�����邷��ɂ́AScrollPattern �������Ă����ʃR���g���[�����g���� Scroll�܂���SetScrollPercent�ŃX�N���[�����܂��B
Scroll�ł�ScrollAmount �N���X�ɒ�`����Ă��� LargeDecrement=0�ALargeIncrement=3�ANoAmount=2�ASmallDecrement=1�ASmallIncrement=4 ���g����Large��Page Up/Down�L�[�ASmall�͖��L�[���̃X�N���[�����s�Ȃ��܂��B
SetScrollPercent�̓p�[�Z���g�ʒu(float 0����100)���w�肵�܂��B ���������Ɛ��������̎w�肪�”\�ł��B�X�N���[�������Ȃ��Ƃ���-1���w�肵�܂��B �S�̂����ɃX�N���[������Ȃ�SetScrollPercent�Ŏw�肷��̂��y�����ł��B �K�������w�肵���p�[�Z���g�ʒu�Ɉړ�����킯�ł͂Ȃ� �X�N���[���̈ړ��P�ʂɉ������A���̋ߕӂ̈ړ��”\�Ȉʒu�փX�N���[�����܂��B

# �����ړ��Ȃ��A���� PageUp 
obj.GetScrollPattern().Scroll(ui.ScrollAmount.NoAmount, ui.ScrollAmount.LargeDecrement)

# �����ړ��Ȃ��A����50%�ʒu��
obj.GetScrollPattern().SetScrollPercent(-1, 50.0)
obj.GetScrollPattern().SetScrollPercent(ui.ScrollPattern.NoScrollValue, 50.0)

�X�N���[���o�[�ŃX�N���[������B
ScrollBarControl�ł�GetRangeValuePattern()�Ŏ��o���� RangeValuePattern��SetValue(value)�Ƀp�[�Z���g�ʒu���w�肷�邱�ƂŃX�N���[���ł��܂��B �����p�Ɛ����p�͕ʁX�ɗL��܂��B�K�������w�肵���p�[�Z���g�ʒu�Ɉړ�����킯�ł͂Ȃ� �X�N���[���̈ړ��P�ʂɉ������A���̋ߕӂ̈ړ��”\�Ȉʒu�փX�N���[�����܂��B

s=obj.ScrollBarControl(Name="����")
r = s.GetRangeValuePattern()
r.SetValue(30.0)                   # 30%�ʒu�t�߂ɃX�N���[��

��ʏ�Ɍ����Ă��邩���m�F����B
Control�N���X�ɂ�bool�^��IsOffscreen�v���p�e�B���L��܂��̂� ���̔h���N���X�ł����ꂪ�g���܂��B

obj.IsOffscreen   # True or False

�X�N���[���������ʓ��ɕ\������Ă��邩����Œ��ׂ��܂��B IsOffscreen�ł��̂Ō����ĂȂ��Ƃ�True�ł��BFalse�̎��A��ʓ��ɕ\������Ă܂��B

�l��ݒ肷��

toggle switch �R���g���[��

obj.GetTogglePattern().Toggle()

slider �R���g���[��
v = �ݒ�ʒu

obj.GetRangeValuePattern().SetValue(float(v))

radio button �R���g���[��

obj.GetSelectionItemPattern().Select()

combo box �R���g���[��
v = �I�����閼�O

x = Select(itemName =v)

check box �R���g���[��
v = �ݒ�l

if obj.GetTogglePattern().ToggleState != int(v):
    obj.GetTogglePattern().Toggle()

edit �R���g���[��
v = ������

obj.GetValuePattern().Value()       # �l���o��
obj.GetValuePattern().SetValue(v)   # �l�ݒ�

button �R���g���[��

obj.GetInvokePattern().Invoke()

�Ώۃv���O�����̎������@�ɂ���Ă͕ʓr�l�����Ȃ���΂Ȃ�Ȃ������L��܂��B �T�^�I�ȕ��@�̂ЂƂ‚Ƃ��ĎQ�l�ɂ��ĉ������B

�Ō�̎� Clik & SendKey(s)

�I�u�W�F�N�g��uiautomation�����肭�����Ȃ��Ƃ��ɂ͍ŏI��i��Click��SendKey(s)���� ���؂邱�ƂɂȂ�܂��B���̏ꍇ�A��ʂ̉𑜓x��ΏۃE�C���h�E�̃T�C�Y�ɂ���� �\�����@���ω�����ꍇ�������̂ŁA�ł��邾�����������ɂȂ�悤�ɑΏۂ��ő剻������ �E�����h�E�T�C�Y���w�肵���肷��̂����S�ł��B

�܂��A���쎞�͕K����ʏ�̃g�b�v(���ɉB�ꂸ)�Ɍ�����悤�ɂ���K�v���L��܂��B

uiautomation�Ŏg����@�\�� �h�L�������g���Q�� ���ĉ������B

���O������΋@�\�����������z�����‚��Ǝv���܂��B

�}�C�N���\�t�g�̃y�C���g�ł��G�������������L�ɋ����Ă݂܂��B �e�X�g��Windows7�ł���Ă��܂��̂�Windows10�ł͏�肭�s���Ȃ���������܂���B ���������肢���܂��B

���̗�Ɠ��������͏Ȃ��Ă��܂��̂ŁAimport��Q�Ɗ֐��ނ͑��̗�����p���Ă��������B

def multi_line(base,points):
    p1 = p2 = []
    for point in points:
        if len(p1)==0:
            p1 = point
        else:
            p2 = point
            ui.DragDrop(base[0]+p1[0],base[1]+p1[1],base[0]+p2[0],base[1]+p2[1],2)
            print(p1,p2)
            p1 = p2
def main():
    proc = subprocess.Popen('cmd /c "mspaint.exe"')
    w = ui.GetRootControl().WindowControl(searchDepth=2,RegexName=r'.*�y�C���g')
    w.GetWindowPattern().SetWindowVisualState(ui.WindowVisualState.Maximized)
    dump_structure(w,1,5)
    p_area = w.GetFirstChildControl()
    while(p_area.BoundingRectangle.bottom - p_area.BoundingRectangle.top < 300):
        p_area = p_area.GetNextSiblingControl()
    print(p_area.BoundingRectangle)

    x = p_area.BoundingRectangle.left +10
    y = p_area.BoundingRectangle.top +10
    multi_line([x,y],[[50,50],[100,50],[100,80]])
    ui.Click(318,70) ## Text button
    ui.Click(x+10,y)
    ui.SendKeys('Test Paint')
    ui.Click(x,y) ## �m�肳����
    ui.Click(930,60) ## �΃{�^��
    ui.Click(446,104) ## ���{�^��
    ui.DragDrop(x+150,y,x+200,y+50)
    ui.Click(x,y) ## �m�肳����

mspaint.exe���N�����Ă���A����Window�����‚��܂��B �����ł̓��j���[���̕\���̕ω����N�����Ȃ��悤�ɍő剻���Ă��܂��B ��ʂ̉�����1024pixcel�����̏ꍇ�ɂ͏㕔�̃��{���̕\�����ς��{�^���̈ʒu������܂��B

mspaint��uiautomation�����PaneControl����‚������Ă���悤�Ɍ����܂��� ���̕��т͏����ɂ���ĕω�����悤�ł��B���ׁ̈A�����ł͏c�̃T�C�Y��300pixel�ȏ�� PaneControl��`��̈�Ƃ��Č��o���Ă��܂��B

Control�N���X�ɂ�BoundingRectangle�Ƃ����������L���ʏ�̗̈���(Rect class)�������Ă��܂��B
BoundingRectangle.top : ���y�ʒu
BoundingRectangle.left : ����x�ʒu
BoundingRectangle.bottom : ����y�ʒu
BoundingRectangle.right : �E��x�ʒu
��������o���ĕ`��̈��N���b�N�̈�̎Q�l�ɂ��܂��B ���S�ɌŒ�Ȃ�A�ΏۃE�C���h�E�̃L���v�`��������ĉ摜�G�f�B�^�ňʒu�𒲂ׂ邱�Ƃ��ł��܂��B ���̏ꍇ�A�E�B���h�E���̈ʒu�ł��̂ŁA�E�C���h�E�̗̈��[left,top]�Ɖ��Z���Ă��������B ui.Click()�Ŏw�肷��ʒu���f�X�N�g�b�v��̃s�N�Z���P�ʂł̐�Έʒu�ł��B �E�C���h�E���̑��Έʒu�ł͗L��܂���B

��͎��ۂɑ��삷��̂Ɠ����悤�ɃN���b�N�ƃL�[���͂��J��Ԃ��܂��B ���̗�ł͕�����₷�����邽�ߕۑ����̏������Ȃ��Ă��܂��B


�ЂƂ܂������܂łŌ��J���܂��B
2021/2/16 : First version
2021/2/21 : �S�̂̍\���\����GetRootControl()�ɕύX�ASetGlobalSearchTimeout����
2021/3/02 : �֐��̃\�[�X�������N�ɒlj�
2021/3/28 : �ŏI��i��Click & SendKey(s)�lj��Aui_lib.py(�\���_���v�Ɉʒu���lj�)
2022/6/14 : GetScrollItemPattern�̒lj����@�����M

News: 2021/01/27
uiautomation���� First version