1# Copyright 2013 The Chromium Authors. All rights reserved. 2# Use of this source code is governed by a BSD-style license that can be 3# found in the LICENSE file. 4 5"""Common helper module for working with Chrome's processes and windows.""" 6 7import psutil 8import re 9import win32gui 10import win32process 11 12 13def GetProcessIDAndPathPairs(): 14 """Returns a list of 2-tuples of (process id, process path). 15 """ 16 process_id_and_path_pairs = [] 17 for process in psutil.process_iter(): 18 try: 19 process_id_and_path_pairs.append((process.pid, process.exe)) 20 except psutil.Error: 21 # It's normal that some processes are not accessible. 22 pass 23 return process_id_and_path_pairs 24 25 26def GetProcessIDs(process_path): 27 """Returns a list of IDs of processes whose path is |process_path|. 28 29 Args: 30 process_path: The path to the process. 31 32 Returns: 33 A list of process IDs. 34 """ 35 return [pid for (pid, path) in GetProcessIDAndPathPairs() if 36 path == process_path] 37 38 39def GetWindowHandles(process_ids): 40 """Returns a list of handles of windows owned by processes in |process_ids|. 41 42 Args: 43 process_ids: A list of process IDs. 44 45 Returns: 46 A list of handles of windows owned by processes in |process_ids|. 47 """ 48 hwnds = [] 49 def EnumerateWindowCallback(hwnd, _): 50 _, found_process_id = win32process.GetWindowThreadProcessId(hwnd) 51 if found_process_id in process_ids and win32gui.IsWindowVisible(hwnd): 52 hwnds.append(hwnd) 53 # Enumerate all the top-level windows and call the callback with the hwnd as 54 # the first parameter. 55 win32gui.EnumWindows(EnumerateWindowCallback, None) 56 return hwnds 57 58 59def WindowExists(process_ids, class_pattern): 60 """Returns whether there exists a window with the specified criteria. 61 62 This method returns whether there exists a window that is owned by a process 63 in |process_ids| and has a class name that matches |class_pattern|. 64 65 Args: 66 process_ids: A list of process IDs. 67 class_pattern: The regular expression pattern of the window class name. 68 69 Returns: 70 A boolean indicating whether such window exists. 71 """ 72 for hwnd in GetWindowHandles(process_ids): 73 if re.match(class_pattern, win32gui.GetClassName(hwnd)): 74 return True 75 return False 76