def test_process_is_running(self): """Tests process is running and wait for exit function""" app = Application() app.start(_notepad_exe()) app.UntitledNotepad.wait("ready") self.assertTrue(app.is_process_running()) self.assertRaises(TimeoutError, lambda: app.wait_for_process_exit(timeout=5, retry_interval=1)) app.kill() app.wait_for_process_exit() self.assertFalse(app.is_process_running())
def restart_if_app_exist(exepath): from pywinauto.application import Application try: app = Application(backend="win32").connect(path=exepath) if app.is_process_running(): app.kill() except Exception: None
def test_should_return_not_running_if_not_started(self): """Tests that works on new instance is_process_running/wait_for_process_exit can be called on not started/disconnected instance """ app = Application() app.wait_for_process_exit(timeout=10, retry_interval=1) self.assertFalse(app.is_process_running())
def test_should_return_not_running_if_failed_to_open_process( self, func_open_process): """Tests error handling wehn OpenProcess return 0 handle Checks is_process_running and wait_for_process_exit works even if OpenProcess returns 0 handle without exception """ func_open_process.return_value = pywintypes.HANDLE(0) app = Application() app.start(_notepad_exe()) app.wait_for_process_exit(timeout=10, retry_interval=1) self.assertFalse(app.is_process_running()) app.kill()
def testConnectWarning3264(self): if not is_x64_OS(): self.defaultTestResult() return app = Application().start(self.sample_exe_inverted_bitness) # Appveyor misteries... self.assertEqual(app.is_process_running(), True) with mock.patch("warnings.warn") as mockWarn: Application().connect(process=app.process) app.kill_() args, kw = mockWarn.call_args assert len(args) == 2 assert "64-bit" in args[0] assert args[1].__name__ == 'UserWarning'
def main(argv): WaitForOrbit() application = Application(backend='uia').connect(title_re='orbitprofiler') if application.is_process_running(): logging.info('Orbit is running.') else: logging.info('Orbit is not running.') # Connect to the first (and only) gamelet. dialog = application.window(title_re='orbitprofiler') dialog.set_focus() # DataItem0 contains the name of the first gamelet. dialog.DataItem0.click_input() dialog.OK.click_input() logging.info('Connected to Gamelet.') # Wait until the service is deployed and the main window is opened. # Waiting for the window does not really work since there is a progress dialog # with an identical title popping up in between. So we just sleep. time.sleep(15) # Choose hello_ggp_stanalone as the process to profile. main_wnd = application.window(title_re='orbitprofiler', found_index=0) main_wnd.ProcessesEdit.type_keys('hello_') # Wait for the game to appear in the ProcessesTreeView. main_wnd.ProcessesTreeView.hello_ggp_stand.wait('exists', timeout=100) main_wnd.ProcessesTreeView.hello_ggp_stand.click_input() logging.info('Selected process "hello_ggp_stand".') # Load debug symbols for hello_ggp_standalone module. time.sleep(2) main_wnd.ModulesTreeView.hello_ggp_standalone.click_input(button='right') main_wnd.LoadSymbols.click_input() logging.info('Loaded symbols for module "hello_ggp_standalone".') # Hook DrawFrame function. main_wnd.TreeView1.DrawFrame.click_input(button='right') main_wnd.Hook.click_input() logging.info('Hooked function "DrawFrame"') # The capture tab can not be found in the usual way so the focus is set by # clicking on the widget. The x-coordinate for the click is obtained from the # mid_point of the capture tab header, the y-coordinate is taken from the # mid_point of the functions tab on the right. # Obtaining the coordinates is done before clicking on the tab since # pywinauto becomes painfully slow once the tab is visible. click_x = main_wnd.captureTabItem.rectangle().mid_point().x click_y = main_wnd.SessionsTreeView.rectangle().mid_point().y # Change into capture tab. main_wnd.captureTabItem.click_input() logging.info('Changed into capture view') # Focus the capture tab and take a five second capture. main_wnd.click_input(coords=(click_x, click_y)) main_wnd.type_keys('X') time.sleep(5) main_wnd.type_keys('X') logging.info('Took a five second capture.') # Check the output in the live tab. DrawFrames should have been called ~300 # times (60 Hz * 5 seconds). children = main_wnd.TreeView.children() for i in range(len(children)): if 'DrawFrame' in children[i].window_text(): num = int(children[i + 1].window_text()) if num < 30 or num > 3000: raise RuntimeError('Wrong number of calls to "DrawFrame": ' + str(num)) else: logging.info('Verified number of calls to "DrawFrame".') main_wnd.CloseButton.click_input() logging.info('Closed Orbit.')
from pywinauto.application import Application import pywinauto import sys import os # start app os.system('start ms-settings:notifications') app = Application(backend='uia').connect(title_re="Settings") print(app.is_process_running(), type(app)) framewin = app.window(class_name='ApplicationFrameWindow') print(framewin.exists()) # corewin = framewin.window(class_name='Windows.UI.Core.CoreWindow') # print(corewin.exists()) # targetwin = corewin.window(class_name='LandmarkTarget') # print(targetwin.exists()) # control = targetwin.window(auto_id='ItemsControlScrollViewer') # print(control.exists()) # notifications = control.window(title='Notifications', class_name='GroupItem') # print(notifications.exists()) # toggle_btn = notifications.window(auto_id='SystemSettings_Notifications_ShowAppNotifications_ToggleSwitch') # print(toggle_btn.exists()) toggle_btn_fast = framewin.window( auto_id='SystemSettings_Notifications_ShowAppNotifications_ToggleSwitch') print(toggle_btn_fast.exists())
def find_window(backend, obj, level, dict, traces): success = True for loop_x in range(0, len(dict)): try: temp_list = dict[str(loop_x + 1)].split(",") name = None process = None handle = None path = None class_name = None class_name_re = None title = None title_re = None control_id = None control_type = None auto_id = None framework_id = None for loop_y in range(0, len(temp_list)): if "name=" in str(temp_list[loop_y]).strip(): name = str(temp_list[loop_y]).strip() name = name[5:] elif "process=" in str(temp_list[loop_y]).strip(): process = str(temp_list[loop_y]).strip() process = process[8:] elif "handle=" in str(temp_list[loop_y]).strip(): handle = str(temp_list[loop_y]).strip() handle = handle[7:] elif "path=" in str(temp_list[loop_y]).strip(): path = str(temp_list[loop_y]).strip() path = path[5:] elif "class_name=" in str(temp_list[loop_y]).strip(): class_name = str(temp_list[loop_y]).strip() class_name = class_name[11:] elif "class_name_re=" in str(temp_list[loop_y]).strip(): class_name_re = str(temp_list[loop_y]).strip() class_name_re = class_name_re[14:] elif "title=" in str(temp_list[loop_y]).strip(): title = str(temp_list[loop_y]).strip() title = title[6:] elif "title_re=" in str(temp_list[loop_y]).strip(): title_re = str(temp_list[loop_y]).strip() title_re = title_re[9:] elif "control_id=" in str(temp_list[loop_y]).strip(): control_id = str(temp_list[loop_y]).strip() control_id = control_id[11:] elif "control_type=" in str(temp_list[loop_y]).strip(): control_type = str(temp_list[loop_y]).strip() control_type = control_type[13:] elif "auto_id=" in str(temp_list[loop_y]).strip(): auto_id = str(temp_list[loop_y]).strip() auto_id = auto_id[8:] elif "framework_id=" in str(temp_list[loop_y]).strip(): framework_id = str(temp_list[loop_y]).strip() framework_id = framework_id[13:] if level == "app": if path is not None: obj = Application(backend=backend).connect(path=path) elif handle is not None: obj = Application(backend=backend).connect(handle=handle) elif process is not None: obj = Application(backend=backend).connect(process=process) elif title_re is not None: obj = Application(backend=backend).connect( title_re=title_re) else: obj = Application(backend=backend).connect(title=title) try: success = obj.is_process_running() except: success = False break else: if level == "main": if name is not None: obj = obj[name] elif backend == "uia": obj = obj.window(class_name=class_name, class_name_re=class_name_re, title=title, title_re=title_re, control_id=control_id, control_type=control_type, auto_id=auto_id, framework_id=framework_id) else: obj = obj.window(class_name=class_name, class_name_re=class_name_re, title=title, title_re=title_re, control_id=control_id, control_type=control_type) else: if name is not None: obj = obj[name] elif backend == "uia": obj = obj.child_window(class_name=class_name, class_name_re=class_name_re, title=title, title_re=title_re, control_id=control_id, control_type=control_type, auto_id=auto_id, framework_id=framework_id) else: obj = obj.child_window(class_name=class_name, class_name_re=class_name_re, title=title, title_re=title_re, control_id=control_id, control_type=control_type) if traces is True: try: trace_str = level if level is not "main": trace_str = trace_str + " " + str(loop_x + 1) print("") print(datetime.datetime.now().strftime( '%Y-%m-%d %H:%M:%S') + ": " + "\t=== * Locating " + trace_str + " start * ===") print("") obj.print_control_identifiers(depth=1) print("") print(datetime.datetime.now().strftime( '%Y-%m-%d %H:%M:%S') + ": " + "\t=== * Locating " + trace_str + " end * ===") print("") except: if level == "main": print(datetime.datetime.now().strftime( '%Y-%m-%d %H:%M:%S') + ": " + "\tUNABLE TO LOCATE MAIN WINDOW!") else: print(datetime.datetime.now().strftime( '%Y-%m-%d %H:%M:%S') + ": " + "\tUNABLE TO LOCATE CHILD WINDOW " + str(loop_x + 1) + "!") success = False break if not obj.exists(): success = False break except: print(traceback.format_exc()) success = False break if success is True: return obj else: return None
class Client: def __init__(self, path=settings.POKERSTARS['path'], main_window=None, library_dir=None): self.path = path self.app = None self.main_window = None self.player_list = None self.table_list = None self.library_dir = library_dir def connect(self): try: with warnings.catch_warnings(): warnings.simplefilter("ignore") self.app = Application().connect(path=self.path) except ProcessNotFoundError: return False return True def start(self): try: logging.info("Starting PokerStars...") with warnings.catch_warnings(): warnings.simplefilter("ignore") Application().start(self.path) self.app = Application().connect(path=self.path) logging.info("Waiting for the Login window...") login_window = ClientWindow(self, title_re="Login.*") login_window.control.wait('visible', timeout=180) logging.info("The Login window is visible.") logging.info("Closing the Login window.") login_window.close() logging.info("Waiting for main window...") self.main_window = ClientWindow(self, title_re="PokerStars Lobby") self.main_window.control.wait('enabled', timeout=120) logging.info("Main window is enabled.") except AppStartError as e: print(e) return False return True def prepare(self): self.connect_or_start() self.main_window = ClientWindow(self, title_re="PokerStars Lobby") self.move_main_window() for key, value in settings.POKERSTARS['libraries'].items(): library_path = os.path.join(self.library_dir, value) libraries[key] = ImageLibrary(library_path=library_path) self.player_list = ClientList( self.main_window, settings.POKERSTARS['player_list'], row=ListRow.from_dict(settings.POKERSTARS['player_list_row']), items=ListItem.fields_from_dict( settings.POKERSTARS['player_fields']), ) self.table_list = ClientList( self.main_window, settings.POKERSTARS['table_list'], row=ListRow.from_dict(settings.POKERSTARS['table_list_row']), items=ListItem.fields_from_dict( settings.POKERSTARS['table_fields']), ) self.close_not_main_windows() def connect_or_start(self): if self.connect(): return True else: return self.start() def move_main_window(self): self.main_window.control.restore() hwnd = self.main_window.control.handle default_width = settings.POKERSTARS['default_width'] default_height = settings.POKERSTARS['default_height'] x = settings.POKERSTARS['default_x'] y = settings.POKERSTARS['default_y'] win32gui.MoveWindow(hwnd, x, y, default_width, default_height, True) def is_running(self): if self.app is not None and self.app.is_process_running(): return True return False def save_datasets(self, include: list): if libraries: for key in libraries.keys(): if key in include: libraries[key].save_library() def close_not_main_windows(self): top_window = ClientWindow(self) if self.main_window.title != top_window.title: top_window.close()
from pywinauto.application import Application import pywinauto # start app app = Application(backend='uia').start("notepad.exe") print(app.is_process_running()) # app = Application(backend='uia').connect(process=12344) # app = Application(backend='uia').connect(handle=) # app = Application(backend='uia').connect(path="notepad.exe") # app = Application(backend='uia').connect(title_re='.* - 記事本$', class_name='Notepad') # get window dlg_spec = app.window(title_re='.* - 記事本$', class_name='Notepad') # dlg_spec = app['未命名 - 記事本'] # dlg_spec = app.window(best_match='未命名 - 記事本') # highlight this window dlg_spec.draw_outline() # write something edit_spec = dlg_spec.child_window(title="文字編輯器", auto_id="15", control_type="Edit") edit_spec.set_text('99999') # dlg_spec.menu_select("編輯 -> 取代(R)...") # get infos # dlg_spec.print_control_identifiers() # dlg_spec.dump_tree() # dlg_spec.print_ctrl_ids() # get child window and invoke
app = Application(backend="uia").connect(path=TI_PATHEXE, title="TradeIdeasPro") pdebug("Already running, attaching to the process ID.") except: pdebug("Application not found, trying to start it.") os.system(TI_SHELLPATH) time.sleep(5) app = Application(backend="uia").connect(path=TI_PATHEXE, title="TradeIdeasPro") # Grab a shell for keyboard entry kbshell = win32com.client.Dispatch("WScript.Shell") # Check if the program is running. if app.is_process_running(): pdebug("Confirming Trade-Ideas is running ... ") # Grab the right program, and select File -> Load Layout dlg = app.window(name_re=".*Trade-Ideas.*") dlg.set_focus().type_keys("%FL") # Doing this manually seems to be a lot quicker than with the PyWinAuto hooks. if get_window_focus_retry('Open'): kbshell.SendKeys(_FN, 0) time.sleep(.2) kbshell.SendKeys("~") else: pdebug('Can not capture the open window, closing.') quit(1)