Merge lp:~brian.curtin/ubuntuone-windows-installer/installer-fixes into lp:ubuntuone-windows-installer

Proposed by Brian Curtin
Status: Merged
Approved by: Brian Curtin
Approved revision: 164
Merged at revision: 159
Proposed branch: lp:~brian.curtin/ubuntuone-windows-installer/installer-fixes
Merge into: lp:ubuntuone-windows-installer
Diff against target: 262 lines (+156/-33)
1 file modified
scripts/ubuntuone.xml (+156/-33)
To merge this branch: bzr merge lp:~brian.curtin/ubuntuone-windows-installer/installer-fixes
Reviewer Review Type Date Requested Status
Roberto Alsina (community) Approve
Mike McCracken (community) Approve
Review via email: mp+145999@code.launchpad.net

Commit message

- Make installer smarter by shutting down existing Ubuntu One applications, uninstalling the previous version, and installing on a clean base. (lp:1111899)

Description of the change

This proposal makes the installer a lot smarter in the case of an upgrade, which we sometimes see issues with, and upgrades are the likely case of ZipImportErrors we've been seeing.

There are several parts here:

1. Stop any existing Ubuntu One applications before continuing the installer. If we can find u1sdtool, run it with -q to safely stop syncdaemon. After that, we run a piece of vbscript to use WMI and query the system for all running U1 executables, then terminate all of them.

2. If we can find an uninstaller, back it up and run our uninstall. We have to put the backed up version back so future installers can do the same. We do this inside a progress bar display because this could take a few seconds that might leave people wondering what the installer is doing. On my VMs, it could take 10 seconds from click to the time you see the actual installation part begin, so displaying this progress bar holds them over.

3. I've added showMessageOnError=0 and abortOnError=0 to the places where we run programs that could possibly fail, especially in the pre-installation phase. All of the runProgram's where we're using those attributes should not cause the whole installation to fail, so we can move on from them if they cause problems. They'll be logged in the install.log file, but should present nothing to the user.

4. I've removed a special case of the installer to not start up U1CP on upgrade installs because of our previous issues with installing over the top of things. Now that we do an uninstall and then a clean install, we can safely start up the control panel regardless of whether it was a first-time install or upgrade.

I also had to update the unattendedModeUI to include dialogs for our uninstaller run. It's now minimalWithDialogs.

Note: This has been tested on XP, Vista, and 8. All of them are able to do a successful clean install followed by an upgrade.

To post a comment you must log in.
Revision history for this message
Mike McCracken (mikemc) wrote :

Looks good to me, although I'd like to test it IRL but I'm not sure how.

I'm also not totally clear on why we need to run a backup of the uninstaller and then copy it back.
Why not just run the uninstaller in place?
And once we've done an uninstall followed by an install, why are we putting back the old uninstaller? Isn't there an uninstaller installed by the install step, and if there isn't anymore, why do we still need the old one?

review: Needs Information
Revision history for this message
Brian Curtin (brian.curtin) wrote :

The reason we do the backup is because once the installer finishes, it generates its own uninstaller. It fills the uninstall.dat with the files it created (including the dat file itself and uninstall.exe) so that when uninstall.exe runs, it knows what to remove.

If we run uninstall.exe during the process, it'll end up removing itself at the end of the uninstall, and then the *installer* gets confused at the end because it can't find that uninstall.dat from the previous install. This is true of "upgrade" install processes -- note on line 30 of the diff where we have to state it's an upgrade - not doing so throws other things off.

In order to work around this, we create a copy of uninstall.exe and uninstall.dat. We then run our backup copies so they don't get cleaned up in the uninstall process, then we put them back in place before the installer goes to read them and create the new versions. I don't know why the installer can't just say "oops, didn't find the previous uninstall, just create a new one as if this is a clean install", but it ends up just ignoring the uninstall regeneration part and then you have to delete everything manually.

Revision history for this message
Mike McCracken (mikemc) :
review: Approve
Revision history for this message
Roberto Alsina (ralsina) :
review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'scripts/ubuntuone.xml'
2--- scripts/ubuntuone.xml 2013-01-28 20:33:17 +0000
3+++ scripts/ubuntuone.xml 2013-01-31 23:50:27 +0000
4@@ -78,18 +78,7 @@
5 <platforms>osx</platforms>
6 </folder>
7 </folderList>
8- <preInstallationActionList>
9- <actionGroup>
10- <actionList>
11- <setInstallerVariable name="installationType" value="upgrade"/>
12- </actionList>
13
14- <!-- We assume an existing installation if ${installdir}/uninstall.exe exists -->
15- <ruleList>
16- <fileTest condition="exists" path="${installdir}/uninstall.exe"/>
17- </ruleList>
18- </actionGroup>
19- </preInstallationActionList>
20 <startMenuShortcutList>
21 <startMenuShortcut>
22 <comment>Uninstall ${product_fullname}</comment>
23@@ -155,7 +144,117 @@
24 </ruleList>
25 </throwError>
26 </initializationActionList>
27+ <preInstallationActionList>
28+ <actionGroup>
29+ <actionList>
30+ <setInstallerVariable name="installationType" value="upgrade"/>
31+ </actionList>
32+ <ruleList>
33+ <fileTest condition="exists" path="${installdir}/uninstall.exe"/>
34+ </ruleList>
35+ </actionGroup>
36+ <!-- Don't go down if we can't find/run u1sdtool, this
37+ case will still occur on a clean install. -->
38+ <runProgram>
39+ <abortOnError>0</abortOnError>
40+ <showMessageOnError>0</showMessageOnError>
41+ <program>${installdir}/dist/u1sdtool.exe</program>
42+ <programArguments>-q</programArguments>
43+ <ruleList>
44+ <fileTest condition="exists" path="${installdir}/dist/u1sdtool.exe"/>
45+ </ruleList>
46+ </runProgram>
47+ <!-- We need to kill any existing U1 executables. This script
48+ will find any of the listed executables names which are
49+ running and then terminate them. -->
50+ <writeFile>
51+ <path>${system_temp_directory}/killall.vbs</path>
52+ <text>Option Explicit
53+Dim wmi, process, processes
54+
55+' Connect to the local machine
56+Set wmi = GetObject("winmgmts:{impersonationLevel=impersonate}!\\.\root\cimv2")
57+
58+' Find a list of all possible Ubuntu One executables that could be running.
59+' NOTE: We expect ubuntuone-syncdaemon to have been shutdown via u1sdtool
60+' prior to running this, but if we get this far and it has failed to
61+' shutdown nicely, we do want to kill it before continuing.
62+Set processes = wmi.ExecQuery _
63+("Select * from Win32_Process Where Name Like '%ubuntu%'")
64+
65+' Terminate each process that isn't our installer.
66+For Each process in processes
67+If InStr(1, process.Name, "windows-installer") = 0 Then
68+ process.Terminate()
69+End If
70+Next
71+
72+WScript.Quit 0
73+ </text>
74+ </writeFile>
75+ <runProgram>
76+ <program>cscript</program>
77+ <programArguments>/NOLOGO "${system_temp_directory}/killall.vbs"</programArguments>
78+ <!-- Don't stop if this doesn't work. We can more than
79+ likely live just fine. -->
80+ <abortOnError>0</abortOnError>
81+ <showMessageOnError>0</showMessageOnError>
82+ <ruleList>
83+ <fileTest condition="exists" path="${system_temp_directory}/killall.vbs"/>
84+ </ruleList>
85+ </runProgram>
86+ <showProgressDialog>
87+ <title>Please wait...</title>
88+ <actionList>
89+ <!-- Make a backup of uninstall.exe. The uninstaller gets
90+ confused when it goes to access uninstall.dat so
91+ we operate on our own copies. -->
92+ <copyFile>
93+ <destination>${installdir}/uninstall-backup.exe</destination>
94+ <origin>${installdir}/uninstall.exe</origin>
95+ <ruleList>
96+ <fileTest condition="exists" path="${installdir}/uninstall.exe"/>
97+ </ruleList>
98+ </copyFile>
99+ <copyFile>
100+ <destination>${installdir}/uninstall-backup.dat</destination>
101+ <origin>${installdir}/uninstall.dat</origin>
102+ <ruleList>
103+ <fileTest condition="exists" path="${installdir}/uninstall.dat"/>
104+ </ruleList>
105+ </copyFile>
106+ <runProgram>
107+ <program>${installdir}/uninstall-backup.exe</program>
108+ <programArguments>--mode unattended</programArguments>
109+ <progressText>Uninstalling previous version</progressText>
110+ <ruleList>
111+ <fileTest condition="exists" path="${installdir}/uninstall-backup.exe"/>
112+ </ruleList>
113+ </runProgram>
114+ </actionList>
115+ </showProgressDialog>
116+ </preInstallationActionList>
117 <postInstallationActionList>
118+ <!-- Replace the uninstaller and dat file so they
119+ can be used by InstallBuilder -->
120+ <copyFile>
121+ <destination>${installdir}\uninstall.exe</destination>
122+ <origin>${installdir}\uninstall-backup.exe</origin>
123+ <ruleList>
124+ <fileExists>
125+ <path>${installdir}\uninstall-backup.exe</path>
126+ </fileExists>
127+ </ruleList>
128+ </copyFile>
129+ <copyFile>
130+ <destination>${installdir}\uninstall.dat</destination>
131+ <origin>${installdir}\uninstall-backup.dat</origin>
132+ <ruleList>
133+ <fileExists>
134+ <path>${installdir}\uninstall-backup.dat</path>
135+ </fileExists>
136+ </ruleList>
137+ </copyFile>
138 <registrySet>
139 <key>HKEY_LOCAL_MACHINE\SOFTWARE\${project.fullName}\</key>
140 <name>path-ubuntuone-syncdaemon</name>
141@@ -187,6 +286,8 @@
142 <platformTest type="windows-7" />
143 <platformTest type="windows-8" />
144 </ruleList>
145+ <abortOnError>0</abortOnError>
146+ <showMessageOnError>0</showMessageOnError>
147 </runProgram>
148 <runProgram>
149 <!-- Outbound Firewall allowance -->
150@@ -199,6 +300,8 @@
151 <platformTest type="windows-7" />
152 <platformTest type="windows-8" />
153 </ruleList>
154+ <abortOnError>0</abortOnError>
155+ <showMessageOnError>0</showMessageOnError>
156 </runProgram>
157 <runProgram>
158 <program>netsh.exe</program>
159@@ -207,17 +310,14 @@
160 <!-- This usage of netsh is for XP. -->
161 <platformTest type="windows-xp" />
162 </ruleList>
163+ <abortOnError>0</abortOnError>
164+ <showMessageOnError>0</showMessageOnError>
165 </runProgram>
166 <runProgram>
167 <program>${windows_folder_system}\RunDll32.exe</program>
168 <programArguments>"${installdir}\dist\VistaLib32.dll" RunNonElevated "${installdir}\dist\ubuntuone-control-panel-qt.exe" --installer --with-icon &amp;</programArguments>
169 <useMSDOSPath>0</useMSDOSPath>
170 <ruleList>
171- <compareText>
172- <logic>does_not_equal</logic>
173- <text>${installationType}</text>
174- <value>upgrade</value>
175- </compareText>
176 <platformTest>
177 <type>windows-x86</type>
178 </platformTest>
179@@ -228,27 +328,11 @@
180 <programArguments>"${installdir}\dist\VistaLib64.dll" RunNonElevated "${installdir}\dist\ubuntuone-control-panel-qt.exe" --installer --with-icon &amp;</programArguments>
181 <useMSDOSPath>0</useMSDOSPath>
182 <ruleList>
183- <compareText>
184- <logic>does_not_equal</logic>
185- <text>${installationType}</text>
186- <value>upgrade</value>
187- </compareText>
188 <platformTest>
189 <type>windows-x64</type>
190 </platformTest>
191 </ruleList>
192 </runProgram>
193- <!-- TODO: remove this showInfo? -->
194- <showInfo>
195- <text>Please reboot to finish upgrade.</text>
196- <ruleList>
197- <compareText>
198- <logic>equals</logic>
199- <text>${installationType}</text>
200- <value>upgrade</value>
201- </compareText>
202- </ruleList>
203- </showInfo>
204 <createDirectory>
205 <path>${windows_folder_common_appdata}\ubuntuone</path>
206 </createDirectory>
207@@ -351,7 +435,46 @@
208 <deleteFile>
209 <path>c:\vc_red.cab</path>
210 </deleteFile>
211+ <deleteFile>
212+ <path>${installdir}/uninstall-backup.exe</path>
213+ <ruleList>
214+ <fileExists>
215+ <path>${installdir}/uninstall-backup.exe</path>
216+ </fileExists>
217+ </ruleList>
218+ </deleteFile>
219+ <deleteFile>
220+ <path>${installdir}/uninstall-backup.dat</path>
221+ <ruleList>
222+ <fileExists>
223+ <path>${installdir}/uninstall-backup.dat</path>
224+ </fileExists>
225+ </ruleList>
226+ </deleteFile>
227 </postInstallationActionList>
228+ <preUninstallationActionList>
229+ <deleteFile>
230+ <!-- Since install.log is added programmatically by BitRock
231+ itself, rather than copied, it doesn't get removed on
232+ uninstall. -->
233+ <path>${installDir}/install.log</path>
234+ <ruleList>
235+ <fileExists>
236+ <path>${installdir}\install.log</path>
237+ </fileExists>
238+ </ruleList>
239+ </deleteFile>
240+ <deleteFile>
241+ <!-- Since update.ini is added programmatically rather than
242+ copied, it doesn't get removed on uninstall. -->
243+ <path>${installDir}/update.ini</path>
244+ <ruleList>
245+ <fileExists>
246+ <path>${installdir}\update.ini</path>
247+ </fileExists>
248+ </ruleList>
249+ </deleteFile>
250+ </preUninstallationActionList>
251 <compressionAlgorithm>lzma</compressionAlgorithm>
252 <defaultInstallationMode>unattended</defaultInstallationMode>
253 <disableSplashScreen>1</disableSplashScreen>
254@@ -359,7 +482,7 @@
255 <enableTimestamp>1</enableTimestamp>
256 <installationLogFile>${installdir}/install.log</installationLogFile>
257 <saveRelativePaths>1</saveRelativePaths>
258- <unattendedModeUI>minimal</unattendedModeUI>
259+ <unattendedModeUI>minimalWithDialogs</unattendedModeUI>
260 <vendor>Canonical</vendor>
261 <windowsSoftwareRegistryPrefix>${product_fullname}</windowsSoftwareRegistryPrefix>
262 <customLanguageFileList>

Subscribers

People subscribed via source and target branches