OLD | NEW |
1 # Copyright 2013 The Chromium Authors. All rights reserved. | 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 | 2 # Use of this source code is governed by a BSD-style license that can be |
3 # found in the LICENSE file. | 3 # found in the LICENSE file. |
4 | 4 |
5 """Uninstalls Chrome. | 5 """Uninstalls Chrome. |
6 | 6 |
7 This script reads the uninstall command from registry, calls it, and verifies | 7 This script reads the uninstall command from registry, calls it, and verifies |
8 the output status code. | 8 the output status code. |
9 """ | 9 """ |
10 | 10 |
11 import _winreg | 11 import _winreg |
12 import optparse | 12 import optparse |
13 import subprocess | 13 import subprocess |
14 import sys | 14 import sys |
15 | 15 |
16 | 16 |
17 def main(): | 17 def main(): |
18 parser = optparse.OptionParser(description='Uninstall Chrome.') | 18 parser = optparse.OptionParser(description='Uninstall Chrome.') |
19 parser.add_option('--system-level', action='store_true', dest='system_level', | 19 parser.add_option('--system-level', action='store_true', dest='system_level', |
20 default=False, help='Uninstall Chrome at system level.') | 20 default=False, help='Uninstall Chrome at system level.') |
21 parser.add_option('--chrome-long-name', default='Google Chrome', | 21 parser.add_option('--chrome-long-name', default='Google Chrome', |
22 help='Google Chrome or Chromium)') | 22 help='Google Chrome or Chromium)') |
| 23 parser.add_option('--interactive', action='store_true', dest='interactive', |
| 24 default=False, help='Ask before uninstalling Chrome.') |
| 25 parser.add_option('--no-error-if-absent', action='store_true', |
| 26 dest='no_error_if_absent', default=False, |
| 27 help='No error if the registry key for uninstalling Chrome ' |
| 28 'is absent.') |
23 options, _ = parser.parse_args() | 29 options, _ = parser.parse_args() |
24 | 30 |
25 # TODO(sukolsak): Add support for uninstalling MSI-based Chrome installs when | 31 # TODO(sukolsak): Add support for uninstalling MSI-based Chrome installs when |
26 # we support testing MSIs. | 32 # we support testing MSIs. |
27 if options.system_level: | 33 if options.system_level: |
28 root_key = _winreg.HKEY_LOCAL_MACHINE | 34 root_key = _winreg.HKEY_LOCAL_MACHINE |
29 else: | 35 else: |
30 root_key = _winreg.HKEY_CURRENT_USER | 36 root_key = _winreg.HKEY_CURRENT_USER |
31 sub_key = ('SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\%s' % | 37 sub_key = ('SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\%s' % |
32 options.chrome_long_name) | 38 options.chrome_long_name) |
33 # Query the key. It will throw a WindowsError if the key doesn't exist. | 39 # Query the key. It will throw a WindowsError if the key doesn't exist. |
34 try: | 40 try: |
35 key = _winreg.OpenKey(root_key, sub_key, 0, _winreg.KEY_QUERY_VALUE) | 41 key = _winreg.OpenKey(root_key, sub_key, 0, _winreg.KEY_QUERY_VALUE) |
36 except WindowsError: | 42 except WindowsError: |
| 43 if options.no_error_if_absent: |
| 44 return 0 |
37 raise KeyError('Registry key %s\\%s is missing' % ( | 45 raise KeyError('Registry key %s\\%s is missing' % ( |
38 'HKEY_LOCAL_MACHINE' if options.system_level else 'HKEY_CURRENT_USER', | 46 'HKEY_LOCAL_MACHINE' if options.system_level else 'HKEY_CURRENT_USER', |
39 sub_key)) | 47 sub_key)) |
| 48 if options.interactive: |
| 49 prompt = ('Warning: This will uninstall %s at %s. Do you want to continue? ' |
| 50 '(y/N) ' % (options.chrome_long_name, |
| 51 'system-level' if |
| 52 options.system_level else 'user-level')) |
| 53 if raw_input(prompt).strip() != 'y': |
| 54 print >> sys.stderr, 'User aborted' |
| 55 return 1 |
40 uninstall_string, _ = _winreg.QueryValueEx(key, 'UninstallString') | 56 uninstall_string, _ = _winreg.QueryValueEx(key, 'UninstallString') |
41 exit_status = subprocess.call(uninstall_string + ' --force-uninstall', | 57 exit_status = subprocess.call(uninstall_string + ' --force-uninstall', |
42 shell=True) | 58 shell=True) |
43 # The exit status for successful uninstallation of Chrome is 19 (see | 59 # The exit status for successful uninstallation of Chrome is 19 (see |
44 # chrome/installer/util/util_constants.h). | 60 # chrome/installer/util/util_constants.h). |
45 if exit_status != 19: | 61 if exit_status != 19: |
46 raise Exception('Could not uninstall Chrome. The installer exited with ' | 62 raise Exception('Could not uninstall Chrome. The installer exited with ' |
47 'status %d.' % exit_status) | 63 'status %d.' % exit_status) |
48 return 0 | 64 return 0 |
49 | 65 |
50 | 66 |
51 if __name__ == '__main__': | 67 if __name__ == '__main__': |
52 sys.exit(main()) | 68 sys.exit(main()) |
OLD | NEW |