324f5338582151bc857a4ec583021250689add8a
[pithos-ms-client] / trunk%2FNetSparkle%2FNetSparkleDownloadProgress.cs
1 using System;
2 using System.Collections.Generic;
3 using System.ComponentModel;
4 using System.Data;
5 using System.Drawing;
6 using System.Linq;
7 using System.Text;
8 using System.Windows.Forms;
9 using System.Threading;
10 using System.Net;
11 using System.IO;
12 using System.Diagnostics;
13 using System.Reflection;
14 using log4net;
15
16 namespace AppLimit.NetSparkle
17 {
18     public partial class NetSparkleDownloadProgress : Form
19     {
20         private static readonly ILog Log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
21
22         private String _tempName;
23         private NetSparkleAppCastItem _item;
24         private String _referencedAssembly;
25         private Sparkle _sparkle;
26         private Boolean _unattend;
27
28         public NetSparkleDownloadProgress(Sparkle sparkle, NetSparkleAppCastItem item, String referencedAssembly, Image appIcon, Icon windowIcon, Boolean Unattend)
29         {
30             InitializeComponent();
31
32             if (appIcon != null)
33                 imgAppIcon.Image = appIcon;
34
35             if (windowIcon != null)
36                 Icon = windowIcon;
37
38             // store the item
39             _sparkle = sparkle;
40             _item = item;
41             _referencedAssembly = referencedAssembly;
42             _unattend = Unattend;
43
44             // init ui
45             btnInstallAndReLaunch.Visible = false;
46             lblHeader.Text = lblHeader.Text.Replace("APP", item.AppName + " " + item.Version);
47             progressDownload.Maximum = 100;
48             progressDownload.Minimum = 0;
49             progressDownload.Step = 1;
50
51             // show the right 
52             Size = new Size(Size.Width, 107);
53             lblSecurityHint.Visible = false;                
54             
55             // get the filename of the download lin
56             String[] segments = item.DownloadLink.Split('/');
57             String fileName = segments[segments.Length - 1];
58
59             // get temp path
60             _tempName = Environment.ExpandEnvironmentVariables("%temp%\\" + fileName);
61
62             // start async download
63             WebClient Client = new WebClient();
64             Client.DownloadProgressChanged += new DownloadProgressChangedEventHandler(Client_DownloadProgressChanged);
65             Client.DownloadFileCompleted += new AsyncCompletedEventHandler(Client_DownloadFileCompleted);
66
67             Uri url = new Uri(item.DownloadLink);
68
69             Client.DownloadFileAsync(url, _tempName);
70         }
71
72         private void Client_DownloadFileCompleted(object sender, AsyncCompletedEventArgs e)
73         {
74             progressDownload.Visible = false;
75             btnInstallAndReLaunch.Visible = true;
76
77             if (e.Error != null)
78             {
79                 Log.Error("Update download failed ",e.Error);
80                 Size = new Size(Size.Width, 137);
81                 lblSecurityHint.Text = "An error occured while downloading the update. Please try again later.";
82                 lblSecurityHint.Visible = true;
83                 BackColor = Color.Tomato;
84                 _sparkle.ReportDiagnosticMessage("Failed downloading file to: " + _tempName);
85                 btnInstallAndReLaunch.Click-=btnInstallAndReLaunch_Click;
86                 btnInstallAndReLaunch.Text = "Close";
87                 btnInstallAndReLaunch.Click+=(s,args)=> Close();
88                 btnInstallAndReLaunch.Visible = true;
89                 return;
90             }
91
92             // report message            
93             _sparkle.ReportDiagnosticMessage("Finished downloading file to: " + _tempName);
94
95             // check if we have a dsa signature in appcast            
96             if (_item.DSASignature == null || _item.DSASignature.Length == 0)
97             {
98                 _sparkle.ReportDiagnosticMessage("No DSA check needed");
99             }
100             /*else
101             {
102                 Boolean bDSAOk = false;
103
104             // report
105             _sparkle.ReportDiagnosticMessage("Performing DSA check");
106
107             // get the assembly
108             if (File.Exists(_tempName))
109             {
110                 // check if the file was downloaded successfully
111                 String absolutePath = Path.GetFullPath(_tempName);
112                 if (!File.Exists(absolutePath))
113                     throw new FileNotFoundException();
114
115                 // get the assembly reference from which we start the update progress
116                 // only from this trusted assembly the public key can be used
117                 Assembly refassembly = System.Reflection.Assembly.GetEntryAssembly();
118                 if (refassembly != null)
119                 {
120                     // Check if we found the public key in our entry assembly
121                     if (NetSparkleDSAVerificator.ExistsPublicKey("NetSparkle_DSA.pub"))
122                     {
123                         // check the DSA Code and modify the back color            
124                         NetSparkleDSAVerificator dsaVerifier = new NetSparkleDSAVerificator("NetSparkle_DSA.pub");
125                         bDSAOk = dsaVerifier.VerifyDSASignature(_item.DSASignature, _tempName);
126                     }
127                 }
128             }
129
130                 if (!bDSAOk)
131             {
132                 Size = new Size(Size.Width, 137);
133                 lblSecurityHint.Visible = true;
134                 BackColor = Color.Tomato;
135         }
136             }*/
137                
138             // Check the unattended mode
139             if (_unattend)
140                 btnInstallAndReLaunch_Click(null, null);
141         }
142                
143         private void Client_DownloadProgressChanged(object sender, DownloadProgressChangedEventArgs e)
144         {
145             progressDownload.Value = e.ProgressPercentage;            
146         }
147
148         private void btnInstallAndReLaunch_Click(object sender, EventArgs e)
149         {
150             try
151             {
152
153                 // get the commandline 
154                 String cmdLine = Environment.CommandLine;
155                 String workingDir = Environment.CurrentDirectory;
156
157                 // generate the batch file path
158
159                 String cmd = Environment.ExpandEnvironmentVariables("%temp%\\" + Guid.NewGuid() + ".cmd");
160                 String installerCMD;
161
162                 // get the file type
163                 var extension = Path.GetExtension(_tempName).ToLower();
164                 switch (extension)
165                 {
166                     case ".exe":
167                         installerCMD = String.Format("\"{0}\" /silent /norestart", _tempName);
168                         break;
169                     case ".msi":
170                         installerCMD = String.Format("msiexec /i \"{0}\"", _tempName);
171                         break;
172                     default:
173                         MessageBox.Show("Updater not supported, please execute " + _tempName + " manually", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
174                         Environment.Exit(-1);
175                         return;
176                 }
177
178                 // generate the batch file                
179                 _sparkle.ReportDiagnosticMessage("Generating MSI batch in " + Path.GetFullPath(cmd));
180
181                 using (var write = new StreamWriter(cmd))
182                 {
183                     write.WriteLine(installerCMD);
184                     write.WriteLine("cd " + workingDir);
185                     write.WriteLine(cmdLine);
186                     write.Close();
187                 }
188
189                 // report
190                 _sparkle.ReportDiagnosticMessage("Going to execute batch: " + cmd);
191
192                 // start the installer helper
193                 var process = new Process();
194                 process.StartInfo.FileName = cmd;
195                 process.StartInfo.WindowStyle = ProcessWindowStyle.Hidden;
196                 process.Start();
197
198                 // quit the app
199                 Environment.Exit(0);
200             }
201             catch (Exception exc)
202             {
203                 
204                 Log.Error("Error while launching the update", exc);
205                 this.DialogResult = DialogResult.Cancel;
206                 MessageBox.Show("An error occured while executing the update.", "Update failed", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
207             }
208         }
209     }
210 }