public void ApplyUpdate(AppInfo appInfo, UpdateInfo info, UpdateHost updateInfoSource) { string lockFile = InstallationSettings.InstallationFolder + "/Updater.lock"; if (File.Exists(lockFile)) { throw new Exception("Could not update: the application folder is already locked by another updater instance."); } else { File.Create(lockFile).Close(); } TriggerProgressEvent(0, "Calculating updater tasks"); FileIndex index = FileIndex.Deserialize(InstallationSettings.InstallationFolder + "/UpdateIndex.dat"); UpdateTask[] tasks = GetUpdaterTasks(appInfo, info, updateInfoSource, index); List <UpdateTask> failedTasks = RunTasks(tasks, true, 10); TriggerProgressEvent(percentageDone, "Retrying failed tasks"); for (int i = 0; i < failedTasks.Count; i++) { UpdateTask task = failedTasks[i]; try { task.Run(); } catch (WebException ex) { if (MessageBox.Show("Updater could not download file: " + ex.Message + "\r\n(" + ex.Data["Target"] + ")", "Failed to download file", MessageBoxButtons.RetryCancel, MessageBoxIcon.Error).Equals(DialogResult.Retry)) { i--; //Retry } else { Application.Exit(); } } catch (UnauthorizedAccessException ex) { if (MessageBox.Show("Updater could access file or folder: " + ex.Message + "\r\n(" + ex.Data["Target"] + ")", "Failed to download file", MessageBoxButtons.RetryCancel, MessageBoxIcon.Error).Equals(DialogResult.Retry)) { i--; //Retry } else { Application.Exit(); } } } TriggerProgressEvent(98, "Updating local file index"); index = new FileIndex(index.appID); index.applicationVersion = info.version; index.files.AddRange(info.fileChecksums.Keys); index.Serialize(InstallationSettings.InstallationFolder + "/UpdateIndex.dat"); File.Delete(lockFile); }
public void InstallApplication(Action finishCallback) { if (!Directory.Exists(InstallationSettings.InstallationFolder)) { Directory.CreateDirectory(InstallationSettings.InstallationFolder); } string lockFile = InstallationSettings.InstallationFolder + "/Updater.lock"; if (System.IO.File.Exists(lockFile)) { string message = "The chosen installation folder contains updater files. Installing in this folder may corrupt previous installations. Force installation?"; if (MessageBox.Show(null, message, "Folder contains updater traces", MessageBoxButtons.YesNo, MessageBoxIcon.Error) == System.Windows.Forms.DialogResult.Yes) { System.IO.File.Delete(lockFile); } else { Application.Exit(); } } FileIndex newIndex = new FileIndex(LauncherSettings.AppID); newIndex.Serialize(InstallationSettings.InstallationFolder + "/UpdateIndex.dat"); Updater updater = new Updater(); UpdateProgressWindow progressWindow = new UpdateProgressWindow(updater); progressWindow.SetProgress(0, "Retrieving update info"); updater.RetrieveAppInfo((appInfo, host) => { if (appInfo == null) { MessageBox.Show(progressWindow, "Cannot install: No valid download mirrors online.", "Failed to install", MessageBoxButtons.OK, MessageBoxIcon.Error); Application.Exit(); } updater.RetrieveUpdateInfo(appInfo, host, appInfo.LatestVersion, (updateInfo, updateHost) => { Action startUpdate = (() => { if (updateInfo == null) { MessageBox.Show("No valid update info found."); //TODO: Handle this. Should either search for new appInfo host or fail. } progressWindow.SetProgress(20, "Applying updates"); updater.ApplyUpdate(appInfo, updateInfo, updateHost); progressWindow.SetProgress(90, "Registering installation"); try { CreateUninstallRegistryEntry(); SetInstallationFolder(InstallationSettings.InstallationFolder); if (InstallationSettings.CreateDesktopShortcut) { CreateDesktopShortcut(); } if (InstallationSettings.CreateStartMenuEntry) { CreateStartMenuEntry(); } } catch (Exception ex) { MessageBox.Show( "An exception occured while registering the application. \r\n" + ex.Message + "\r\nTo uninstall the application run the updater with -uninstall -forceInstallDir <installfolder>", "Error" ); } progressWindow.Invoke((Action)(() => { progressWindow.Close(); })); InstallationFinishedForm finishedForm = new InstallationFinishedForm(); finishedForm.ShowDialog(); finishCallback.Invoke(); }); Thread updateThread = new Thread(new ThreadStart(startUpdate)); updateThread.Name = "Update thread"; updateThread.IsBackground = true; updateThread.Start(); }); }); progressWindow.Show(); }