• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 ctypes
8import pywintypes
9import re
10import win32con
11import win32gui
12import win32process
13
14
15def GetProcessIDAndPathPairs():
16  """Returns a list of 2-tuples of (process id, process path).
17
18  This is needed because psutil is not available on Windows slave machines (see:
19  http://crbug.com/257696).
20  TODO(sukolsak): Use psutil.process_iter() once it becomes available.
21  """
22  process_id_and_path_pairs = []
23  for process_id in win32process.EnumProcesses():
24    process_handle = ctypes.windll.kernel32.OpenProcess(
25        win32con.PROCESS_QUERY_INFORMATION | win32con.PROCESS_VM_READ, False,
26        process_id)
27    if not process_handle:
28      continue
29    try:
30      process_path = win32process.GetModuleFileNameEx(process_handle, 0)
31      process_id_and_path_pairs.append((process_id, process_path))
32    except pywintypes.error:
33      # It's normal that some processes are not accessible.
34      pass
35  return process_id_and_path_pairs
36
37
38def GetProcessIDs(process_path):
39  """Returns a list of IDs of processes whose path is |process_path|.
40
41  Args:
42    process_path: The path to the process.
43
44  Returns:
45    A list of process IDs.
46  """
47  return [pid for (pid, path) in GetProcessIDAndPathPairs() if
48          path == process_path]
49
50
51def GetWindowHandles(process_ids):
52  """Returns a list of handles of windows owned by processes in |process_ids|.
53
54  Args:
55    process_ids: A list of process IDs.
56
57  Returns:
58    A list of handles of windows owned by processes in |process_ids|.
59  """
60  hwnds = []
61  def EnumerateWindowCallback(hwnd, _):
62    _, found_process_id = win32process.GetWindowThreadProcessId(hwnd)
63    if found_process_id in process_ids and win32gui.IsWindowVisible(hwnd):
64      hwnds.append(hwnd)
65  # Enumerate all the top-level windows and call the callback with the hwnd as
66  # the first parameter.
67  win32gui.EnumWindows(EnumerateWindowCallback, None)
68  return hwnds
69
70
71def WindowExists(process_ids, class_pattern):
72  """Returns whether there exists a window with the specified criteria.
73
74  This method returns whether there exists a window that is owned by a process
75  in |process_ids| and has a class name that matches |class_pattern|.
76
77  Args:
78    process_ids: A list of process IDs.
79    class_pattern: The regular expression pattern of the window class name.
80
81  Returns:
82    A boolean indicating whether such window exists.
83  """
84  for hwnd in GetWindowHandles(process_ids):
85    if re.match(class_pattern, win32gui.GetClassName(hwnd)):
86      return True
87  return False
88