Merge lp:~nataliabidart/ubuntuone-control-panel/uninstall into lp:ubuntuone-control-panel
- uninstall
- Merge into trunk
Proposed by
Natalia Bidart
Status: | Merged |
---|---|
Approved by: | Natalia Bidart |
Approved revision: | 310 |
Merged at revision: | 307 |
Proposed branch: | lp:~nataliabidart/ubuntuone-control-panel/uninstall |
Merge into: | lp:ubuntuone-control-panel |
Diff against target: |
475 lines (+174/-122) 7 files modified
ubuntuone/controlpanel/gui/qt/controlpanel.py (+3/-4) ubuntuone/controlpanel/gui/qt/gui.py (+1/-2) ubuntuone/controlpanel/gui/qt/tests/test_wizard.py (+12/-1) ubuntuone/controlpanel/gui/qt/wizard.py (+4/-8) ubuntuone/controlpanel/utils/__init__.py (+8/-4) ubuntuone/controlpanel/utils/tests/test_windows.py (+103/-69) ubuntuone/controlpanel/utils/windows.py (+43/-34) |
To merge this branch: | bzr merge lp:~nataliabidart/ubuntuone-control-panel/uninstall |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Manuel de la Peña (community) | Approve | ||
Brian Curtin (community) | Approve | ||
Review via email: mp+100012@code.launchpad.net |
Commit message
- When user rejects the License, also uninstall the application (LP: #968327).
Description of the change
To post a comment you must log in.
- 307. By Natalia Bidart
-
Merged trunk in.
- 308. By Natalia Bidart
-
Merged trunk in.
- 309. By Natalia Bidart
-
- No more runas as parameter to shellexecute.
- 310. By Natalia Bidart
-
Restoring the 'runas' param for autoupdate.
Revision history for this message
Manuel de la Peña (mandel) wrote : | # |
Everything looks good from spain.
review:
Approve
Preview Diff
[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1 | === modified file 'ubuntuone/controlpanel/gui/qt/controlpanel.py' |
2 | --- ubuntuone/controlpanel/gui/qt/controlpanel.py 2012-03-21 19:17:21 +0000 |
3 | +++ ubuntuone/controlpanel/gui/qt/controlpanel.py 2012-03-30 17:37:31 +0000 |
4 | @@ -1,5 +1,5 @@ |
5 | # -*- coding: utf-8 -*- |
6 | - |
7 | +# |
8 | # Copyright 2012 Canonical Ltd. |
9 | # |
10 | # This program is free software: you can redistribute it and/or modify it |
11 | @@ -174,7 +174,6 @@ |
12 | @log_call(logger.info) |
13 | def start_from_license(self): |
14 | """Use the license page as first page.""" |
15 | - # license |
16 | - self.ui.wizard.setStartId(self.ui.wizard.pages[ |
17 | - self.ui.wizard.license_page]) |
18 | + license_id = self.ui.wizard.pages[self.ui.wizard.license_page] |
19 | + self.ui.wizard.setStartId(license_id) |
20 | self.ui.wizard.restart() |
21 | |
22 | === modified file 'ubuntuone/controlpanel/gui/qt/gui.py' |
23 | --- ubuntuone/controlpanel/gui/qt/gui.py 2012-03-26 13:23:57 +0000 |
24 | +++ ubuntuone/controlpanel/gui/qt/gui.py 2012-03-30 17:37:31 +0000 |
25 | @@ -43,8 +43,7 @@ |
26 | self.ui.setupUi(self) |
27 | self.close_callback = close_callback |
28 | self._setup() |
29 | - self.quit_action = QtGui.QAction(self, |
30 | - triggered=self.close) |
31 | + self.quit_action = QtGui.QAction(self, triggered=self.close) |
32 | self.quit_action.setShortcuts(["Ctrl+q", "Ctrl+w"]) |
33 | self.addAction(self.quit_action) |
34 | self.installer = installer |
35 | |
36 | === modified file 'ubuntuone/controlpanel/gui/qt/tests/test_wizard.py' |
37 | --- ubuntuone/controlpanel/gui/qt/tests/test_wizard.py 2012-03-26 21:00:47 +0000 |
38 | +++ ubuntuone/controlpanel/gui/qt/tests/test_wizard.py 2012-03-30 17:37:31 +0000 |
39 | @@ -157,6 +157,7 @@ |
40 | @defer.inlineCallbacks |
41 | def setUp(self): |
42 | yield super(UbuntuOneWizardTestCase, self).setUp() |
43 | + self.patch(gui.utils, 'uninstall_application', self.fail) |
44 | self.patch(self.ui.confirm_dialog, 'exec_', |
45 | lambda: self.confirm_response) |
46 | |
47 | @@ -260,7 +261,7 @@ |
48 | button.click() |
49 | |
50 | self.assertEqual(self._called, (signal_args, {}), |
51 | - msg % (name, signal, signal_args)) |
52 | + msg % (name, signal, signal_args)) |
53 | self._called = False |
54 | |
55 | def test_done_rejected(self): |
56 | @@ -336,6 +337,16 @@ |
57 | page_name = 'license' |
58 | stage_name = 'install' |
59 | |
60 | + @defer.inlineCallbacks |
61 | + def setUp(self): |
62 | + yield super(UbuntuOneWizardLicensePage, self).setUp() |
63 | + self.patch(gui.utils, 'uninstall_application', self._set_called) |
64 | + |
65 | + def test_done_rejected(self): |
66 | + """When the wizard is closed on the final page, emit rejected.""" |
67 | + super(UbuntuOneWizardLicensePage, self).test_done_rejected() |
68 | + self.assertEqual(self._called, ((), {})) |
69 | + |
70 | |
71 | class UbuntuOneWizardLoginTestCase(UbuntuOneWizardTestCase): |
72 | """Test the login through the wizard.""" |
73 | |
74 | === modified file 'ubuntuone/controlpanel/gui/qt/wizard.py' |
75 | --- ubuntuone/controlpanel/gui/qt/wizard.py 2012-03-26 20:15:58 +0000 |
76 | +++ ubuntuone/controlpanel/gui/qt/wizard.py 2012-03-30 17:37:31 +0000 |
77 | @@ -23,7 +23,7 @@ |
78 | from ubuntu_sso.qt.sso_wizard_page import BaseWizardPage |
79 | from ubuntu_sso.utils.ui import CLOSE_AND_SETUP_LATER |
80 | |
81 | -from ubuntuone.controlpanel import cache |
82 | +from ubuntuone.controlpanel import cache, utils |
83 | from ubuntuone.controlpanel.logger import log_call, setup_logging |
84 | from ubuntuone.controlpanel.gui import ( |
85 | APP_NAME, |
86 | @@ -342,13 +342,9 @@ |
87 | response = self.confirm_dialog.exec_() |
88 | if response == QtGui.QDialog.Accepted: |
89 | logger.warning('UbuntuOneWizard: user canceled setup.') |
90 | - self.rejected.emit() |
91 | - elif (self.currentId() == self.pages[self.license_page]): |
92 | - response = self.confirm_dialog.exec_() |
93 | - if response == QtGui.QDialog.Accepted: |
94 | - logger.warning('UbuntuOneWizard: user wants to uninstall.') |
95 | - # TODO: needs implementation in this project |
96 | - ##qt.utils.uninstall_application() |
97 | + if self.currentId() == self.pages[self.license_page]: |
98 | + logger.warning('UbuntuOneWizard: user wants to uninstall.') |
99 | + utils.uninstall_application() |
100 | self.rejected.emit() |
101 | else: |
102 | super(UbuntuOneWizard, self).done(result) |
103 | |
104 | === modified file 'ubuntuone/controlpanel/utils/__init__.py' |
105 | --- ubuntuone/controlpanel/utils/__init__.py 2012-03-22 23:28:19 +0000 |
106 | +++ ubuntuone/controlpanel/utils/__init__.py 2012-03-30 17:37:31 +0000 |
107 | @@ -32,19 +32,23 @@ |
108 | # ignore issues with the name of the method |
109 | # pylint: disable=C0103 |
110 | |
111 | +no_op = lambda *args, **kwargs: None |
112 | + |
113 | # import the platform dependent code. |
114 | if sys.platform == 'win32': |
115 | from ubuntuone.controlpanel.utils import windows |
116 | + add_to_autostart = windows.add_to_autostart |
117 | are_updates_present = windows.are_updates_present |
118 | default_folders = windows.default_folders |
119 | perform_update = windows.perform_update |
120 | - add_to_autostart = windows.add_to_autostart |
121 | + uninstall_application = windows.uninstall_application |
122 | else: |
123 | from ubuntuone.controlpanel.utils import linux |
124 | - are_updates_present = lambda *args, **kwargs: False |
125 | + add_to_autostart = no_op |
126 | + are_updates_present = no_op |
127 | default_folders = linux.default_folders |
128 | - perform_update = lambda *args, **kwargs: None |
129 | - add_to_autostart = lambda *args, **kwargs: None |
130 | + perform_update = no_op |
131 | + uninstall_application = no_op |
132 | |
133 | # pylint: enable=C0103 |
134 | |
135 | |
136 | === modified file 'ubuntuone/controlpanel/utils/tests/test_windows.py' |
137 | --- ubuntuone/controlpanel/utils/tests/test_windows.py 2012-03-27 18:55:37 +0000 |
138 | +++ ubuntuone/controlpanel/utils/tests/test_windows.py 2012-03-30 17:37:31 +0000 |
139 | @@ -1,7 +1,6 @@ |
140 | # -*- coding: utf-8 -*- |
141 | - |
142 | # |
143 | -# Copyright 2011 Canonical Ltd. |
144 | +# Copyright 2011-2012 Canonical Ltd. |
145 | # |
146 | # This program is free software: you can redistribute it and/or modify it |
147 | # under the terms of the GNU General Public License version 3, as published |
148 | @@ -28,6 +27,34 @@ |
149 | # let me use protected methods |
150 | # pylint: disable=W0212 |
151 | |
152 | +SOME_EXE_NAME = 'foo.exe' |
153 | + |
154 | + |
155 | +class FrozenTestCase(TestCase): |
156 | + """A base test case for handling frozen/not frozen systems.""" |
157 | + |
158 | + frozen = True |
159 | + executable = 'path/to/current/exe/ubuntuone/dist/executable.exe' |
160 | + |
161 | + @defer.inlineCallbacks |
162 | + def setUp(self): |
163 | + """Set the different tests.""" |
164 | + yield super(FrozenTestCase, self).setUp() |
165 | + |
166 | + for attr_name in ('frozen', 'executable'): |
167 | + value_not_set = object() |
168 | + value = getattr(utils.windows.sys, attr_name, value_not_set) |
169 | + |
170 | + if self.frozen is not None: |
171 | + setattr(utils.windows.sys, attr_name, getattr(self, attr_name)) |
172 | + elif self.frozen is None and value is not value_not_set: |
173 | + delattr(utils.windows.sys, attr_name) |
174 | + |
175 | + if self.frozen is not None and value is value_not_set: |
176 | + self.addCleanup(delattr, utils.windows.sys, attr_name) |
177 | + elif value is not value_not_set: |
178 | + self.addCleanup(setattr, utils.windows.sys, attr_name, value) |
179 | + |
180 | |
181 | class AutoupdaterTestCase(TestCase): |
182 | """Test the code that is used for the auto update process.""" |
183 | @@ -36,7 +63,9 @@ |
184 | def setUp(self): |
185 | """Prepare for the diff tests.""" |
186 | yield super(AutoupdaterTestCase, self).setUp() |
187 | - self.auto_update_path = r'path\to\exe' |
188 | + self._base_path = r'path\to\exe' |
189 | + self.auto_update_path = os.path.join(self._base_path, |
190 | + utils.windows.AUTOUPDATE_EXE_NAME) |
191 | self.return_from_call = 0 |
192 | self.command = None |
193 | self.args = [] |
194 | @@ -48,8 +77,8 @@ |
195 | return self.return_from_call |
196 | |
197 | self.patch(utils.windows, 'getProcessValue', fake_execute_process) |
198 | - self.patch(utils.windows, '_get_update_path', |
199 | - lambda: self.auto_update_path) |
200 | + self.patch(utils.windows, 'get_exe_path', |
201 | + lambda exe_name: os.path.join(self._base_path, exe_name)) |
202 | |
203 | @defer.inlineCallbacks |
204 | def test_are_updates_present_true(self): |
205 | @@ -81,11 +110,9 @@ |
206 | """Test the method that performs the update.""" |
207 | self.patch(utils.windows.win32api, 'ShellExecute', self._set_called) |
208 | utils.perform_update() |
209 | - self.assertIn(self.auto_update_path, self._called[0][2]) |
210 | - self.assertEqual('runas', self._called[0][1]) |
211 | - self.assertEqual('--unattendedmodeui none', self._called[0][3]) |
212 | - self.assertEqual('', self._called[0][4]) |
213 | - self.assertEqual(0, self._called[0][5]) |
214 | + args = (None, 'runas', self.auto_update_path, |
215 | + '--unattendedmodeui none', '', 0) |
216 | + self.assertEqual(self._called, (args, {})) |
217 | |
218 | |
219 | class FakeOpenKey(object): |
220 | @@ -217,15 +244,14 @@ |
221 | self.test_special_folders(names=('PERSONAL', 'MYMUSIC', 'MYPICTURES')) |
222 | |
223 | |
224 | -class GetPathTestCase(TestCase): |
225 | - """Test the code that is used for the auto update process.""" |
226 | +class GetExePathTestCase(FrozenTestCase): |
227 | + """Test the path calculator when sys is frozen.""" |
228 | |
229 | @defer.inlineCallbacks |
230 | def setUp(self): |
231 | """Set the different tests.""" |
232 | - yield super(GetPathTestCase, self).setUp() |
233 | + yield super(GetExePathTestCase, self).setUp() |
234 | self.called = [] |
235 | - self.exec_path = 'path/to/current/exe' |
236 | self.exists = True |
237 | |
238 | def fake_abspath(path): |
239 | @@ -248,62 +274,70 @@ |
240 | self.patch(utils.windows.os.path, 'dirname', fake_dirname) |
241 | self.patch(utils.windows.os.path, 'exists', fake_exists) |
242 | |
243 | - def _delete_frozen_state(self): |
244 | - """Delete the frozen state.""" |
245 | - del utils.windows.sys.frozen |
246 | - del utils.windows.sys.executable |
247 | - |
248 | - def test_get_auto_update_path_frozen(self): |
249 | - """Test the method used to get the autoupdate.""" |
250 | - # patch the diff parts of sys so that we get fake paths |
251 | - is_frozen = hasattr(utils.windows.sys, 'frozen') |
252 | - if not is_frozen: |
253 | - utils.windows.sys.frozen = True |
254 | - utils.windows.sys.executable = self.exec_path |
255 | - self.addCleanup(self._delete_frozen_state) |
256 | - |
257 | - # called method and assert that we have the correct result |
258 | - path = utils.windows._get_update_path() |
259 | - self.assertEqual(os.path.join(self.exec_path, |
260 | - utils.windows.AUTOUPDATE_EXE_NAME), path) |
261 | - self.assertTrue('os.path.abspath' in self.called) |
262 | - self.assertTrue('os.path.dirname' in self.called) |
263 | - self.assertTrue('os.path.exists' in self.called) |
264 | - |
265 | - def _reset_frozen_state(self, old_frozen, old_exec_path): |
266 | - """Reset the frozen state.""" |
267 | - utils.windows.sys.frozen = old_frozen |
268 | - utils.windows.sys.executable = old_exec_path |
269 | - |
270 | - def _reset__file__(self, path): |
271 | - """Reset the value of __file__.""" |
272 | - utils.windows.__file__ = path |
273 | - |
274 | - def test_get_auto_update_path_not_frozen(self): |
275 | - """Test the method used to get the autoupdate.""" |
276 | - is_frozen = hasattr(utils.windows.sys, 'frozen') |
277 | - if is_frozen: |
278 | - old_frozen = utils.windows.sys.frozen |
279 | - old_exec_path = utils.windows.sys.executable |
280 | - del utils.windows.sys.frozen |
281 | - del utils.windows.sys.executable |
282 | - self.addCleanup(self._reset_frozen_state, old_frozen, |
283 | - old_exec_path) |
284 | - # set a fake __file__ for the module |
285 | - old_file = utils.windows.__file__ |
286 | - utils.windows.__file__ = self.exec_path |
287 | - self.addCleanup(self._reset__file__, old_file) |
288 | - |
289 | - path = utils.windows._get_update_path() |
290 | - self.assertEqual(os.path.join(self.exec_path, |
291 | - utils.windows.AUTOUPDATE_EXE_NAME), path) |
292 | - self.assertEqual(2, self.called.count('os.path.dirname')) |
293 | - self.assertTrue('os.path.exists' in self.called) |
294 | - |
295 | - def test_get_auto_update_path_not_present(self): |
296 | + def test_get_exe_path(self): |
297 | + """Test the method used to get the autoupdate.""" |
298 | + path = utils.windows.get_exe_path(exe_name=SOME_EXE_NAME) |
299 | + |
300 | + self.assertEqual(os.path.join(self.executable, SOME_EXE_NAME), path) |
301 | + |
302 | + expected = ['os.path.abspath', 'os.path.dirname', 'os.path.dirname', |
303 | + 'os.path.exists'] |
304 | + self.assertEqual(expected, self.called) |
305 | + |
306 | + def test_get_exe_path_not_present(self): |
307 | """Test the method used to get the autoupdate.""" |
308 | self.exists = False |
309 | |
310 | # called method and assert that we have the correct result |
311 | - path = utils.windows._get_update_path() |
312 | - self.assertEqual(None, path) |
313 | + path = utils.windows.get_exe_path(exe_name=SOME_EXE_NAME) |
314 | + self.assertTrue(path is None) |
315 | + |
316 | + |
317 | +class GetExePathNotFrozenTestCase(GetExePathTestCase): |
318 | + """Test the path calculator when sys is not frozen.""" |
319 | + |
320 | + frozen = None |
321 | + |
322 | + def test_get_exe_path(self): |
323 | + """Test the method used to get the autoupdate.""" |
324 | + self.patch(utils.windows, '__file__', self.executable) |
325 | + |
326 | + path = utils.windows.get_exe_path(exe_name=SOME_EXE_NAME) |
327 | + self.assertEqual(os.path.join(self.executable, SOME_EXE_NAME), path) |
328 | + |
329 | + expected = ['os.path.dirname', 'os.path.dirname', 'os.path.dirname', |
330 | + 'os.path.exists'] |
331 | + self.assertEqual(expected, self.called) |
332 | + |
333 | + |
334 | +class UninstallApplicationTestCase(FrozenTestCase): |
335 | + """Test the uninstall_application helper when sys is frozen.""" |
336 | + |
337 | + @defer.inlineCallbacks |
338 | + def setUp(self): |
339 | + yield super(UninstallApplicationTestCase, self).setUp() |
340 | + self.patch(utils.windows.win32api, "ShellExecute", self._set_called) |
341 | + self.patch(os.path, "exists", lambda path: True) |
342 | + |
343 | + def test_uninstall(self): |
344 | + """The uninstaller is run.""" |
345 | + utils.uninstall_application() |
346 | + |
347 | + exe_name = utils.windows.UNINSTALL_EXE_NAME |
348 | + uninstall_path = utils.windows.get_exe_path(exe_name=exe_name) |
349 | + self.assertEqual(self._called, |
350 | + ((None, '', uninstall_path, '--mode win32', '', 0), {})) |
351 | + |
352 | + def test_uninstall_exe_not_present(self): |
353 | + """The uninstaller is not run if not available.""" |
354 | + self.patch(os.path, "exists", lambda path: False) |
355 | + |
356 | + utils.uninstall_application() |
357 | + |
358 | + self.assertFalse(self._called) |
359 | + |
360 | + |
361 | +class UninstallApplicationNotFrozenTestCase(UninstallApplicationTestCase): |
362 | + """Test the uninstall_application helper when sys is not frozen.""" |
363 | + |
364 | + frozen = None |
365 | |
366 | === modified file 'ubuntuone/controlpanel/utils/windows.py' |
367 | --- ubuntuone/controlpanel/utils/windows.py 2012-03-23 21:48:53 +0000 |
368 | +++ ubuntuone/controlpanel/utils/windows.py 2012-03-30 17:37:31 +0000 |
369 | @@ -1,7 +1,6 @@ |
370 | # -*- coding: utf-8 -*- |
371 | - |
372 | # |
373 | -# Copyright 2011 Canonical Ltd. |
374 | +# Copyright 2011-2012 Canonical Ltd. |
375 | # |
376 | # This program is free software: you can redistribute it and/or modify it |
377 | # under the terms of the GNU General Public License version 3, as published |
378 | @@ -35,19 +34,41 @@ |
379 | logger = setup_logging('utils.windows') |
380 | AUTOUPDATE_EXE_NAME = 'autoupdate-windows.exe' |
381 | AUTORUN_KEY = r"Software\Microsoft\Windows\CurrentVersion\Run" |
382 | - |
383 | - |
384 | -def _get_update_path(): |
385 | +UNINSTALL_EXE_NAME = 'uninstall.exe' |
386 | + |
387 | + |
388 | +def get_exe_path(exe_name): |
389 | """Return the path in which the autoupdate command is found.""" |
390 | - if hasattr(sys, 'frozen'): |
391 | + if getattr(sys, 'frozen', False): |
392 | exec_path = os.path.abspath(sys.executable) |
393 | else: |
394 | exec_path = os.path.dirname(__file__) |
395 | - folder = os.path.dirname(exec_path) |
396 | - update_path = os.path.join(folder, AUTOUPDATE_EXE_NAME) |
397 | - if os.path.exists(update_path): |
398 | - return update_path |
399 | - return None |
400 | + |
401 | + result = None |
402 | + folder = os.path.dirname(os.path.dirname(exec_path)) |
403 | + exe_path = os.path.join(folder, exe_name) |
404 | + if os.path.exists(exe_path): |
405 | + result = exe_path |
406 | + |
407 | + return result |
408 | + |
409 | + |
410 | +def add_to_autostart(): |
411 | + """Add syncdaemon to the session's autostart.""" |
412 | + if getattr(sys, "frozen", False): |
413 | + sd_path = '"%s"' % os.path.join(os.path.dirname( |
414 | + os.path.abspath(sys.executable)), |
415 | + "ubuntuone-syncdaemon.exe") |
416 | + u1cp_path = '"%s"' % os.path.join(os.path.dirname( |
417 | + os.path.abspath(sys.executable)), |
418 | + "ubuntuone-control-panel-qt.exe") |
419 | + |
420 | + with _winreg.OpenKey(_winreg.HKEY_CURRENT_USER, AUTORUN_KEY, |
421 | + 0, _winreg.KEY_ALL_ACCESS) as key: |
422 | + # pylint: disable=E0602 |
423 | + _winreg.SetValueEx(key, "Ubuntu One", 0, _winreg.REG_SZ, sd_path) |
424 | + _winreg.SetValueEx(key, "Ubuntu One Icon", 0, _winreg.REG_SZ, |
425 | + u1cp_path + " --minimized --with-icon") |
426 | |
427 | |
428 | @defer.inlineCallbacks |
429 | @@ -55,7 +76,7 @@ |
430 | """Return if there are updates for Ubuntu One.""" |
431 | result = False |
432 | retcode = None |
433 | - update_path = _get_update_path() |
434 | + update_path = get_exe_path(exe_name=AUTOUPDATE_EXE_NAME) |
435 | if update_path is not None: |
436 | # If there is an update present we will get 0, non-zero otherwise |
437 | retcode = yield getProcessValue(update_path, args=('--mode', |
438 | @@ -92,27 +113,15 @@ |
439 | |
440 | def perform_update(): |
441 | """Spawn the autoupdate process and call the stop function.""" |
442 | - update_path = _get_update_path() |
443 | + update_path = get_exe_path(exe_name=AUTOUPDATE_EXE_NAME) |
444 | if update_path is not None: |
445 | # lets call the updater with the commands that are required, |
446 | - win32api.ShellExecute(None, 'runas', |
447 | - update_path, |
448 | - '--unattendedmodeui none', '', 0) |
449 | - |
450 | - |
451 | -def add_to_autostart(): |
452 | - """Add syncdaemon to the session's autostart.""" |
453 | - if getattr(sys, "frozen", False): |
454 | - sd_path = '"%s"' % os.path.join(os.path.dirname( |
455 | - os.path.abspath(sys.executable)), |
456 | - "ubuntuone-syncdaemon.exe") |
457 | - u1cp_path = '"%s"' % os.path.join(os.path.dirname( |
458 | - os.path.abspath(sys.executable)), |
459 | - "ubuntuone-control-panel-qt.exe") |
460 | - |
461 | - with _winreg.OpenKey(_winreg.HKEY_CURRENT_USER, AUTORUN_KEY, |
462 | - 0, _winreg.KEY_ALL_ACCESS) as key: |
463 | - # pylint: disable=E0602 |
464 | - _winreg.SetValueEx(key, "Ubuntu One", 0, _winreg.REG_SZ, sd_path) |
465 | - _winreg.SetValueEx(key, "Ubuntu One Icon", 0, _winreg.REG_SZ, |
466 | - u1cp_path + " --minimized --with-icon") |
467 | + win32api.ShellExecute(None, 'runas', update_path, |
468 | + '--unattendedmodeui none', '', 0) |
469 | + |
470 | + |
471 | +def uninstall_application(): |
472 | + """Uninstall Ubuntu One.""" |
473 | + uninstall_path = get_exe_path(exe_name=UNINSTALL_EXE_NAME) |
474 | + if uninstall_path is not None: |
475 | + win32api.ShellExecute(None, '', uninstall_path, '--mode win32', '', 0) |
Looks fine, and IRL tests of uninstallation on Windows XP and Windows 7 both function properly with these changes.