using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Windows.Forms; using System.Threading; using System.Net; using System.IO; using System.Diagnostics; using System.Reflection; using log4net; namespace AppLimit.NetSparkle { public partial class NetSparkleDownloadProgress : Form { private static readonly ILog Log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); private String _tempName; private NetSparkleAppCastItem _item; private String _referencedAssembly; private Sparkle _sparkle; private Boolean _unattend; public NetSparkleDownloadProgress(Sparkle sparkle, NetSparkleAppCastItem item, String referencedAssembly, Image appIcon, Icon windowIcon, Boolean Unattend) { InitializeComponent(); if (appIcon != null) imgAppIcon.Image = appIcon; if (windowIcon != null) Icon = windowIcon; // store the item _sparkle = sparkle; _item = item; _referencedAssembly = referencedAssembly; _unattend = Unattend; // init ui btnInstallAndReLaunch.Visible = false; lblHeader.Text = lblHeader.Text.Replace("APP", item.AppName + " " + item.Version); progressDownload.Maximum = 100; progressDownload.Minimum = 0; progressDownload.Step = 1; // show the right Size = new Size(Size.Width, 107); lblSecurityHint.Visible = false; // get the filename of the download lin String[] segments = item.DownloadLink.Split('/'); String fileName = segments[segments.Length - 1]; // get temp path _tempName = Environment.ExpandEnvironmentVariables("%temp%\\" + fileName); // start async download WebClient Client = new WebClient(); Client.DownloadProgressChanged += new DownloadProgressChangedEventHandler(Client_DownloadProgressChanged); Client.DownloadFileCompleted += new AsyncCompletedEventHandler(Client_DownloadFileCompleted); Uri url = new Uri(item.DownloadLink); Client.DownloadFileAsync(url, _tempName); } private void Client_DownloadFileCompleted(object sender, AsyncCompletedEventArgs e) { progressDownload.Visible = false; btnInstallAndReLaunch.Visible = true; if (e.Error != null) { Log.Error("Update download failed ",e.Error); Size = new Size(Size.Width, 137); lblSecurityHint.Text = "An error occured while downloading the update. Please try again later."; lblSecurityHint.Visible = true; BackColor = Color.Tomato; _sparkle.ReportDiagnosticMessage("Failed downloading file to: " + _tempName); btnInstallAndReLaunch.Click-=btnInstallAndReLaunch_Click; btnInstallAndReLaunch.Text = "Close"; btnInstallAndReLaunch.Click+=(s,args)=> Close(); btnInstallAndReLaunch.Visible = true; return; } // report message _sparkle.ReportDiagnosticMessage("Finished downloading file to: " + _tempName); // check if we have a dsa signature in appcast if (_item.DSASignature == null || _item.DSASignature.Length == 0) { _sparkle.ReportDiagnosticMessage("No DSA check needed"); } /*else { Boolean bDSAOk = false; // report _sparkle.ReportDiagnosticMessage("Performing DSA check"); // get the assembly if (File.Exists(_tempName)) { // check if the file was downloaded successfully String absolutePath = Path.GetFullPath(_tempName); if (!File.Exists(absolutePath)) throw new FileNotFoundException(); // get the assembly reference from which we start the update progress // only from this trusted assembly the public key can be used Assembly refassembly = System.Reflection.Assembly.GetEntryAssembly(); if (refassembly != null) { // Check if we found the public key in our entry assembly if (NetSparkleDSAVerificator.ExistsPublicKey("NetSparkle_DSA.pub")) { // check the DSA Code and modify the back color NetSparkleDSAVerificator dsaVerifier = new NetSparkleDSAVerificator("NetSparkle_DSA.pub"); bDSAOk = dsaVerifier.VerifyDSASignature(_item.DSASignature, _tempName); } } } if (!bDSAOk) { Size = new Size(Size.Width, 137); lblSecurityHint.Visible = true; BackColor = Color.Tomato; } }*/ // Check the unattended mode if (_unattend) btnInstallAndReLaunch_Click(null, null); } private void Client_DownloadProgressChanged(object sender, DownloadProgressChangedEventArgs e) { progressDownload.Value = e.ProgressPercentage; } private void btnInstallAndReLaunch_Click(object sender, EventArgs e) { try { // get the commandline String cmdLine = Environment.CommandLine; String workingDir = Environment.CurrentDirectory; // generate the batch file path String cmd = Environment.ExpandEnvironmentVariables("%temp%\\" + Guid.NewGuid() + ".cmd"); String installerCMD; // get the file type var extension = Path.GetExtension(_tempName).ToLower(); switch (extension) { case ".exe": installerCMD = _tempName; break; case ".msi": installerCMD = String.Format("msiexec /i \"{0}\"", _tempName); break; default: MessageBox.Show("Updater not supported, please execute " + _tempName + " manually", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error); Environment.Exit(-1); return; } // generate the batch file _sparkle.ReportDiagnosticMessage("Generating MSI batch in " + Path.GetFullPath(cmd)); using (var write = new StreamWriter(cmd)) { write.WriteLine(installerCMD); write.WriteLine("cd " + workingDir); write.WriteLine(cmdLine); write.Close(); } // report _sparkle.ReportDiagnosticMessage("Going to execute batch: " + cmd); // start the installer helper var process = new Process(); process.StartInfo.FileName = cmd; process.StartInfo.WindowStyle = ProcessWindowStyle.Hidden; process.Start(); // quit the app Environment.Exit(0); } catch (Exception exc) { Log.Error("Error while launching the update", exc); this.DialogResult = DialogResult.Cancel; MessageBox.Show("An error occured while executing the update.", "Update failed", MessageBoxButtons.OK, MessageBoxIcon.Exclamation); } } } }