private void notifyClient_UpdateAvailable(object sender, UpdateAvailableEventArgs e) { lock (upgradeLock) { try { log.Warn("UpdateAvailable!"); foreach (var key in e.Properties.AllKeys) log.DebugFormat("Property: {0}={1}", key, string.Join(", ", e.Properties.GetValues(key))); if (!string.IsNullOrEmpty(Properties.Settings.Default.Password)) { // Check password if (!Properties.Settings.Default.Password.Equals(e.Properties["password"])) throw new InvalidOperationException("Invalid password"); } notifyClient.PublishStatus("Upgrade started for build: " + e.Properties["build"]); string updaterPath; if (System.IO.Path.IsPathRooted(Properties.Settings.Default.UpdaterFolder)) updaterPath = Properties.Settings.Default.UpdaterFolder; else updaterPath = System.IO.Path.Combine(System.IO.Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), Properties.Settings.Default.UpdaterFolder); string downloadPath; if (System.IO.Path.IsPathRooted(Properties.Settings.Default.DownloadFolder)) downloadPath = Properties.Settings.Default.DownloadFolder; else downloadPath = System.IO.Path.Combine(updaterPath, Properties.Settings.Default.DownloadFolder); try { // Empty download folder System.IO.Directory.Delete(downloadPath, true); } catch { } if (!System.IO.Directory.Exists(downloadPath)) System.IO.Directory.CreateDirectory(downloadPath); var destFiles = new List<string>(); // Download everything var webClient = new System.Net.WebClient(); foreach (var downloadItem in Properties.Settings.Default.Downloads) { string downloadUrl = downloadItem.Trim(); if (!downloadUrl.Contains("/") || !downloadUrl.StartsWith("http", StringComparison.OrdinalIgnoreCase)) continue; downloadUrl = ReplaceProperties(downloadUrl, e.Properties); string filename = downloadUrl.Substring(downloadUrl.LastIndexOf('/') + 1); string destFile = System.IO.Path.Combine(downloadPath, filename); var uri = new Uri(downloadUrl); if (string.IsNullOrEmpty(uri.UserInfo)) webClient.Credentials = null; else { var credInfo = uri.UserInfo.Split(':'); if (credInfo.Length == 2) webClient.Credentials = new System.Net.NetworkCredential(credInfo[0], credInfo[1]); downloadUrl = uri.Scheme + "://" + uri.Host + uri.PathAndQuery; } log.InfoFormat("Downloading from {0}", downloadUrl); webClient.DownloadFile(downloadUrl, destFile); destFiles.Add(destFile); } notifyClient.PublishStatus("Download complete"); if (Properties.Settings.Default.ExtractDownloadedZip) { foreach (var destFile in destFiles) { if (System.IO.Path.GetExtension(destFile).Equals(".zip", StringComparison.OrdinalIgnoreCase)) { notifyClient.PublishStatus("Extracting " + System.IO.Path.GetFileName(destFile)); using (var zipFile = Ionic.Zip.ZipFile.Read(destFile)) { zipFile.ExtractAll(System.IO.Path.GetDirectoryName(destFile), Ionic.Zip.ExtractExistingFileAction.OverwriteSilently); } // Delete the file try { System.IO.File.Delete(destFile); } catch { } } } } // Shut down notify client during upgrade notifyClient.Disconnect(); notifyClient = null; var updaters = Properties.Settings.Default.Updaters; if (updaters == null) updaters = new List<UpdaterConfig>(); if (!string.IsNullOrEmpty(Properties.Settings.Default.UpdaterExecutable)) { updaters.Add(new UpdaterConfig { Executable = Properties.Settings.Default.UpdaterExecutable, Parameters = Properties.Settings.Default.UpdaterParameters }); } var logLines = new List<string>(); bool errors = false; foreach (var updater in updaters) { Process updaterProcess = new Process(); updaterProcess.StartInfo.WorkingDirectory = updaterPath; updaterProcess.StartInfo.FileName = System.IO.Path.Combine(updaterPath, updater.Executable); updaterProcess.StartInfo.Arguments = ReplaceProperties(updater.Parameters, e.Properties); updaterProcess.StartInfo.UseShellExecute = false; updaterProcess.StartInfo.RedirectStandardOutput = true; updaterProcess.StartInfo.RedirectStandardError = true; log.Info("Starting update process"); log.DebugFormat("Launch: {0} {1}", updaterProcess.StartInfo.FileName, updaterProcess.StartInfo.Arguments); updaterProcess.OutputDataReceived += (recv_sender, recv_e) => { if (!string.IsNullOrEmpty(recv_e.Data)) { log.Info(recv_e.Data); logLines.Add("#" + recv_e.Data); } }; updaterProcess.ErrorDataReceived += (recv_sender, recv_e) => { if (!string.IsNullOrEmpty(recv_e.Data)) { log.Error(recv_e.Data); errors = true; logLines.Add("*" + recv_e.Data); } }; updaterProcess.Start(); updaterProcess.BeginOutputReadLine(); updaterProcess.BeginErrorReadLine(); updaterProcess.WaitForExit(); if (updaterProcess.ExitCode != 0) errors = true; updaterProcess.Close(); if (errors) // Stop execution of upgrades if errors detected break; } log.Info("Processing done"); SetupNotifyClient(); notifyClient.Connect(); notifyClient.WaitForConnected(20000); // Send last 10 log messages foreach (var logLine in logLines.Skip(logLines.Count - 10)) notifyClient.PublishStatus(logLine); notifyClient.WaitForEmptyQueue(); if (errors) notifyClient.PublishStatus("Upgrade with errors!!!", false); else notifyClient.PublishStatus("Upgrade done!", true); } catch (Exception ex) { notifyClient.PublishStatus("Exception: " + ex.Message, false); } } }
private void SetupNotifyClient() { notifyClient = new NotifyClient(Properties.Settings.Default.CometURL, Properties.Settings.Default.CometChannel); notifyClient.UpdateAvailable += new EventHandler<UpdateAvailableEventArgs>(notifyClient_UpdateAvailable); }