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.
7 This script sends a WM_CLOSE message to each window of Chrome and waits until
8 the process terminates.
23 def CloseWindows(process_path
):
24 """Closes all windows owned by processes whose exe path is |process_path|.
27 process_path: The path to the executable whose processes will have their
31 A boolean indicating whether the processes successfully terminated within
34 start_time
= time
.time()
35 while time
.time() - start_time
< 25:
36 process_ids
= chrome_helper
.GetProcessIDs(process_path
)
40 for hwnd
in chrome_helper
.GetWindowHandles(process_ids
):
42 win32gui
.PostMessage(hwnd
, win32con
.WM_CLOSE
, 0, 0)
43 except pywintypes
.error
as error
:
44 # It's normal that some window handles have become invalid.
45 if error
.args
[0] != winerror
.ERROR_INVALID_WINDOW_HANDLE
:
51 def KillNamedProcess(process_path
):
52 """ Kills all running exes with the same name as the exe at |process_path|.
55 process_path: The path to an executable.
58 True if running executables were successfully killed. False otherwise.
60 return os
.system('taskkill /f /im %s' % os
.path
.basename(process_path
)) == 0
63 def QuitChrome(chrome_path
):
64 """ Tries to quit chrome in a safe way. If there is still an open instance
65 after a timeout delay, the process is killed the hard way.
68 chrome_path: The path to chrome.exe.
70 if not CloseWindows(chrome_path
):
71 # TODO(robertshield): Investigate why Chrome occasionally doesn't shut down.
72 sys
.stderr
.write('Warning: Chrome not responding to window closure. '
73 'Killing all processes belonging to %s\n' % chrome_path
)
74 KillNamedProcess(chrome_path
)
78 usage
= 'usage: %prog chrome_path'
79 parser
= optparse
.OptionParser(usage
, description
='Quit Chrome.')
80 _
, args
= parser
.parse_args()
82 parser
.error('Incorrect number of arguments.')
85 QuitChrome(chrome_path
)
89 if __name__
== '__main__':