Browse Source

Windows updater can update itself (Fixes issue 593)


git-svn-id: http://svn.dmdirc.com/trunk@3141 00569f92-eb28-0410-84fd-f71c24880f
tags/0.6
Shane Mc Cormack 16 years ago
parent
commit
9cd9f272f1

+ 43
- 30
launcher/windows/DMDirc.dpr View File

@@ -5,7 +5,7 @@ program DMDirc;
5 5
 {$R icon.rc}
6 6
 {$R version.rc}
7 7
 
8
-uses Windows, SysUtils, classes;
8
+uses Windows, SysUtils, classes, StrUtils;
9 9
 
10 10
 // Run an application and wait for it to finish.
11 11
 function ExecAndWait(sProgramToRun: String): Longword;
@@ -41,10 +41,18 @@ begin
41 41
 		dwFlags := STARTF_USESHOWWINDOW;
42 42
 		wShowWindow := SW_SHOWNORMAL;
43 43
 	end;
44
-
44
+	
45 45
 	CreateProcess(nil, PChar(sProgramToRun), nil, nil, False, NORMAL_PRIORITY_CLASS, nil, nil, StartupInfo, ProcessInfo);
46 46
 end;
47 47
 
48
+procedure RunProgram(sProgramToRun: String; wait: boolean);
49
+begin
50
+	if wait then ExecAndWait(sProgramToRun)
51
+	else Launch(sProgramToRun);
52
+end;
53
+
54
+const
55
+	launcherVersion: String = '1';
48 56
 var
49 57
 	errorMessage: String;
50 58
 	javaCommand: String = 'javaw.exe';
@@ -53,13 +61,15 @@ var
53 61
 	i: integer;
54 62
 	hK32: THandle;
55 63
 	jarName: String;
64
+	launcherUpdate: boolean = false;
56 65
 begin
57 66
 	jarName := ExtractFileDir(paramstr(0))+'\DMDirc.jar';
58 67
 	
59 68
 	directory := GetEnvironmentVariable('APPDATA')+'\DMDirc';
60 69
 	if ParamCount > 0 then begin
61 70
 		for i := 1 to ParamCount do begin
62
-			cliParams := cliParams+' '+paramstr(i);
71
+			if AnsiContainsStr(cliParams, ' ') then cliParams := cliParams+' "'+paramstr(i)+'"'
72
+			else cliParams := cliParams+' '+paramstr(i);
63 73
 			if (paramstr(i) = '-d') or (paramstr(i) = '--directory') then begin
64 74
 				if ParamCount > i then begin
65 75
 					directory := paramstr(i+1);
@@ -69,7 +79,8 @@ begin
69 79
 	end;
70 80
 
71 81
 	// Update if needed.
72
-	if FileExists(directory+'\.DMDirc.jar') then begin
82
+	launcherUpdate := FileExists(directory+'\.DMDirc.exe') and FileExists(directory+'\.DMDircUpdater.exe');
83
+	if FileExists(directory+'\.DMDirc.jar') or launcherUpdate then begin
73 84
 		// Vista Sucks.
74 85
 		hK32 := GetModuleHandle('kernel32');
75 86
 		if GetProcAddress(hK32, 'GetLocaleInfoEx') <> nil then begin
@@ -86,32 +97,18 @@ begin
86 97
 				errorMessage := errorMessage+#13#10+'Please click ''Allow'' on the UAC prompt to complete the update, or click no';
87 98
 				errorMessage := errorMessage+#13#10+'here to continue without updating.';
88 99
 				if MessageBox(0, PChar(errorMessage), 'Windows Vista', MB_YESNO) = IDYES then begin
89
-					ExecAndWait('DMDircUpdater.exe '+directory+'\.DMDirc.jar');
100
+					RunProgram('"'+ExtractFileDir(paramstr(0))+'\DMDircUpdater.exe" --UpdateSourceDir "'+directory+'"', not launcherUpdate);
90 101
 				end;
91 102
 			end
92
-			else ExecAndWait('DMDircUpdater.exe '+directory+'\.DMDirc.jar');
103
+			else RunProgram('"'+ExtractFileDir(paramstr(0))+'\DMDircUpdater.exe" --UpdateSourceDir "'+directory+'"', not launcherUpdate);
93 104
 		end
94
-		else ExecAndWait('DMDircUpdater.exe '+directory+'\.DMDirc.jar');
105
+		else RunProgram('"'+ExtractFileDir(paramstr(0))+'\DMDircUpdater.exe" --UpdateSourceDir "'+directory+'"', not launcherUpdate);
95 106
 	end;
96 107
 	
97
-	// Check JVM
98
-	if (ExecAndWait(javaCommand+' -version') <> 0) then begin
99
-		errorMessage := 'No JVM is currently installed.';
100
-		errorMessage := errorMessage+#13#10;
101
-		errorMessage := errorMessage+#13#10+'DMDirc requires a 1.6.0 compatible JVM, you can get one from:';
102
-		errorMessage := errorMessage+#13#10+'http://jdl.sun.com/webapps/getjava/BrowserRedirect';
103
-		errorMessage := errorMessage+#13#10;
104
-		errorMessage := errorMessage+#13#10+'If you feel this is incorrect, or you require some further assistance,';
105
-		errorMessage := errorMessage+#13#10+'please feel free to contact us.';
106
-		
107
-		MessageBox(0, PChar(errorMessage), 'Sorry, DMDirc is unable to continue', MB_OK + MB_ICONSTOP);
108
-	end
109
-	// Else try and run client. (This only asks for help output to check that client
110
-	// runs on this OS, otherwise later segfaults or so would cause the error to
111
-	// appear
112
-	else if FileExists(jarName) then begin
113
-		if (ExecAndWait(javaCommand+' -jar "'+jarName+'" --help') <> 0) then begin
114
-			errorMessage := 'The currently installed version of java is not compatible with DMDirc.';
108
+	if not launcherUpdate then begin
109
+		// Check JVM
110
+		if (ExecAndWait(javaCommand+' -version') <> 0) then begin
111
+			errorMessage := 'No JVM is currently installed.';
115 112
 			errorMessage := errorMessage+#13#10;
116 113
 			errorMessage := errorMessage+#13#10+'DMDirc requires a 1.6.0 compatible JVM, you can get one from:';
117 114
 			errorMessage := errorMessage+#13#10+'http://jdl.sun.com/webapps/getjava/BrowserRedirect';
@@ -121,12 +118,28 @@ begin
121 118
 			
122 119
 			MessageBox(0, PChar(errorMessage), 'Sorry, DMDirc is unable to continue', MB_OK + MB_ICONSTOP);
123 120
 		end
121
+		// Else try and run client. (This only asks for help output to check that client
122
+		// runs on this OS, otherwise later segfaults or so would cause the error to
123
+		// appear
124
+		else if FileExists(jarName) then begin
125
+			if (ExecAndWait(javaCommand+' -jar "'+jarName+'" --help') <> 0) then begin
126
+				errorMessage := 'The currently installed version of java is not compatible with DMDirc.';
127
+				errorMessage := errorMessage+#13#10;
128
+				errorMessage := errorMessage+#13#10+'DMDirc requires a 1.6.0 compatible JVM, you can get one from:';
129
+				errorMessage := errorMessage+#13#10+'http://jdl.sun.com/webapps/getjava/BrowserRedirect';
130
+				errorMessage := errorMessage+#13#10;
131
+				errorMessage := errorMessage+#13#10+'If you feel this is incorrect, or you require some further assistance,';
132
+				errorMessage := errorMessage+#13#10+'please feel free to contact us.';
133
+				
134
+				MessageBox(0, PChar(errorMessage), 'Sorry, DMDirc is unable to continue', MB_OK + MB_ICONSTOP);
135
+			end
136
+			else begin
137
+				Launch(javaCommand+' -ea -jar "'+jarName+'"'+' -l windows-'+launcherVersion+' '+cliParams)
138
+			end;
139
+		end
124 140
 		else begin
125
-			Launch(javaCommand+' -ea -jar "'+jarName+'"'+cliParams)
141
+			errorMessage := 'Your DMDirc installation has been broken. DMDirc.jar no longer exists.';
142
+			MessageBox(0, PChar(errorMessage), 'Sorry, DMDirc is unable to continue', MB_OK + MB_ICONSTOP);
126 143
 		end;
127
-	end
128
-	else begin
129
-		errorMessage := 'Your DMDirc installation has been broken. DMDirc.jar no longer exists.';
130
-		MessageBox(0, PChar(errorMessage), 'Sorry, DMDirc is unable to continue', MB_OK + MB_ICONSTOP);
131 144
 	end;
132 145
 end.

BIN
launcher/windows/DMDirc.exe View File


+ 94
- 12
launcher/windows/DMDircUpdater.dpr View File

@@ -4,30 +4,112 @@ program DMDircUpdater;
4 4
 
5 5
 {$R UAC.rc}
6 6
 
7
-uses Windows, SysUtils, classes;
7
+uses Windows, SysUtils, classes, StrUtils;
8 8
 
9
+// Run an application and don't wait for it to finish.
10
+procedure Launch(sProgramToRun: String);
9 11
 var
10
-	updateFile: String = '';
12
+	StartupInfo: TStartupInfo;
13
+	ProcessInfo: TProcessInformation;
14
+begin
15
+	FillChar(StartupInfo, SizeOf(TStartupInfo), 0);
16
+	with StartupInfo do begin
17
+		cb := SizeOf(TStartupInfo);
18
+		dwFlags := STARTF_USESHOWWINDOW;
19
+		wShowWindow := SW_SHOWNORMAL;
20
+	end;
21
+	MessageBox(0, pchar('Foo: '+sProgramToRun), 'Update Failed', MB_ICONSTOP);
22
+	CreateProcess(nil, PChar(sProgramToRun), nil, nil, False, NORMAL_PRIORITY_CLASS, nil, nil, StartupInfo, ProcessInfo);
23
+end;
24
+
25
+var
26
+	sourceDir: String = '';
27
+	thisDir: String;
28
+	cliParams: String = '';
11 29
 	i: integer;
12 30
 	jarName: String;
31
+	launcherUpdate: boolean = false;
32
+	myName: String;
33
+	canDoMore: boolean = true;
13 34
 begin
14
-	jarName := ExtractFileDir(paramstr(0))+'\DMDirc.jar';
35
+	myName := ExtractFileName(paramstr(0));
36
+	thisDir := ExtractFileDir(paramstr(0));
37
+	jarName := thisDir+'\DMDirc.jar';
15 38
 	
16 39
 	if ParamCount > 0 then begin
17 40
 		for i := 1 to ParamCount do begin
18
-			updateFile := updateFile+' '+paramstr(i);
41
+			if AnsiContainsStr(cliParams, ' ') then cliParams := cliParams+' "'+paramstr(i)+'"'
42
+			else cliParams := cliParams+' '+paramstr(i);
43
+			if (paramstr(i) = '--UpdateSourceDir') then begin // Source Directory
44
+				if ParamCount > i then begin
45
+					sourceDir := paramstr(i+1);
46
+				end;
47
+			end
19 48
 		end;
20 49
 
21
-		if FileExists(pchar(jarName)) then begin
22
-			if not DeleteFile(pchar(jarName)) then begin
23
-				MessageBox(0, 'Unable to delete DMDirc.jar', 'Update Failed', MB_ICONSTOP);
50
+		// Look for a launcher update.
51
+		if FileExists(pchar(sourceDir+'\.DMDirc.exe')) and FileExists(pchar(sourceDir+'\.DMDircUpdater.exe')) then begin
52
+			if myName = 'DMDircUpdater.exe' then begin
53
+				// Windows won't let us overwrite ourself, so we need to copy ourself
54
+				// to another name, and run the new us.
55
+				if CopyFile(pchar(thisDir+'\DMDircUpdater.exe'), pchar(thisDir+'\DMDircLauncherUpdater.exe'), False) then begin
56
+					canDoMore := false;
57
+					Launch('"'+thisDir+'\DMDircLauncherUpdater.exe" '+cliParams);
58
+				end
59
+				else begin
60
+					MessageBox(0, 'Unable to overwrite launcher', 'Launcher Update Failed', MB_ICONSTOP);
61
+				end;
62
+			end
63
+			else begin
64
+				launcherUpdate := true;
65
+				if FileExists(pchar(thisDir+'\DMDirc.exe')) then begin
66
+					if not DeleteFile(pchar(thisDir+'\DMDirc.exe')) then begin
67
+						MessageBox(0, 'Unable to delete DMDirc.exe', 'Update Failed', MB_ICONSTOP);
68
+					end;
69
+				end;
70
+				
71
+				if not FileExists(pchar(thisDir+'\DMDirc.exe')) and MoveFile(pchar(sourceDir+'\.DMDirc.exe'), pchar(thisDir+'\DMDirc.exe')) then begin
72
+					if FileExists(pchar(thisDir+'\DMDircUpdater.exe')) then begin
73
+						if not DeleteFile(pchar(thisDir+'\DMDircUpdater.exe')) then begin
74
+							MessageBox(0, 'Unable to delete DMDircUpdater.exe', 'Update Failed', MB_ICONSTOP);
75
+						end;
76
+					end;
77
+					if not FileExists(pchar(thisDir+'\DMDircUpdater.exe')) and MoveFile(pchar(sourceDir+'\.DMDircUpdater.exe'), pchar(thisDir+'\DMDircUpdater.exe')) then begin
78
+						MessageBox(0, 'Launcher update was successful.', 'Launcher Update Completed', MB_OK);
79
+					end
80
+					else begin
81
+						MessageBox(0, pchar('Unable to update DMDircUpdater.exe'), 'Launcher Update Failed', MB_ICONSTOP);
82
+					end;
83
+				end
84
+				else begin
85
+					MessageBox(0, pchar('Unable to update DMDirc.exe'), 'Launcher Update Failed', MB_ICONSTOP);
86
+				end;
24 87
 			end;
25 88
 		end;
26
-		if MoveFile(pchar(trim(updateFile)), pchar(jarName)) then begin
27
-			MessageBox(0, 'Client update was successful.', 'Update Completed', MB_OK);
28
-		end
29
-		else begin
30
-			MessageBox(0, pchar('Unable to move '''+updateFile+''' to DMDirc.jar'), 'Update Failed', MB_ICONSTOP);
89
+		
90
+		// Look for client update
91
+		if canDoMore then begin
92
+			if FileExists(pchar(sourceDir+'\.DMDirc.jar')) then begin
93
+				if FileExists(pchar(jarName)) then begin
94
+					if not DeleteFile(pchar(jarName)) then begin
95
+						MessageBox(0, 'Unable to delete DMDirc.jar', 'Update Failed', MB_ICONSTOP);
96
+					end;
97
+				end;
98
+				
99
+				if MoveFile(pchar(sourceDir+'\.DMDirc.jar'), pchar(jarName)) then begin
100
+					MessageBox(0, 'Client update was successful.', 'Update Completed', MB_OK);
101
+				end
102
+				else begin
103
+					MessageBox(0, pchar('Unable to move '''+sourceDir+'\.DMDirc.jar'' to '+jarName), 'Update Failed', MB_ICONSTOP);
104
+				end;
105
+			end;
106
+			
107
+			if launcherUpdate then begin
108
+				MessageBox(0, 'The DMDirc launcher has been updated, to complete the update please relaunch DMDirc.', 'Restart Required', MB_OK);
109
+			end;
31 110
 		end;
111
+	end
112
+	else begin
113
+		MessageBox(0, 'This program can not be run on its own.', 'Error', MB_ICONSTOP);
32 114
 	end;
33 115
 end.

BIN
launcher/windows/DMDircUpdater.exe View File


+ 6
- 2
src/com/dmdirc/updater/components/LauncherComponent.java View File

@@ -24,6 +24,7 @@ package com.dmdirc.updater.components;
24 24
 
25 25
 import com.dmdirc.updater.UpdateChecker;
26 26
 import com.dmdirc.updater.UpdateComponent;
27
+import com.dmdirc.util.resourcemanager.ZipResourceManager;
27 28
 
28 29
 import java.io.File;
29 30
 
@@ -92,8 +93,8 @@ public class LauncherComponent implements UpdateComponent {
92 93
     /** {@inheritDoc} */
93 94
     @Override
94 95
     public boolean doInstall(final String path) throws Throwable {
96
+        final File tmpFile = new File(path);
95 97
         if (platform.equalsIgnoreCase("Linux")) {
96
-            final File tmpFile = new File(path);
97 98
             final File targetFile = new File(tmpFile.getParent() + File.separator + ".launcher.sh");
98 99
 
99 100
             if (targetFile.exists()) {
@@ -103,7 +104,10 @@ public class LauncherComponent implements UpdateComponent {
103 104
             tmpFile.renameTo(targetFile);
104 105
             return true;
105 106
         } else {
106
-            throw new UnsupportedOperationException("Not supported yet.");
107
+            final ZipResourceManager ziprm = ZipResourceManager.getInstance(path);
108
+            ziprm.extractResources("", tmpFile.getParent()+ File.separator);
109
+            new File(path).delete();
110
+            return false;
107 111
         }
108 112
     }
109 113
 

Loading…
Cancel
Save