root / trunk / NetSparkle / NetSparkle.cs @ 049333d2
History | View | Annotate | Download (26.1 kB)
1 |
using System; |
---|---|
2 |
using System.Collections.Generic; |
3 |
using System.Linq; |
4 |
using System.Text; |
5 |
using System.ComponentModel; |
6 |
using System.Threading; |
7 |
using System.Net; |
8 |
using System.Windows; |
9 |
using System.Windows.Forms; |
10 |
using System.Drawing; |
11 |
using System.Runtime.InteropServices; |
12 |
using System.Management; |
13 |
using System.Diagnostics; |
14 |
using System.Security.Cryptography.X509Certificates; |
15 |
using System.Net.Security; |
16 |
using Point = System.Drawing.Point; |
17 |
|
18 |
namespace AppLimit.NetSparkle |
19 |
{ |
20 |
public delegate void LoopStartedOperation(Object sender); |
21 |
public delegate void LoopFinishedOperation(Object sender, Boolean UpdateRequired); |
22 |
|
23 |
/// <summary> |
24 |
/// Everytime when netsparkle detects an update the |
25 |
/// consumer can decide what should happen as next with the help |
26 |
/// of the UpdateDatected event |
27 |
/// </summary> |
28 |
public enum nNextUpdateAction |
29 |
{ |
30 |
showStandardUserInterface = 1, |
31 |
performUpdateUnattended = 2, |
32 |
prohibitUpdate = 3 |
33 |
} |
34 |
|
35 |
/// <summary> |
36 |
/// Contains all information for the update detected event |
37 |
/// </summary> |
38 |
public class UpdateDetectedEventArgs : EventArgs |
39 |
{ |
40 |
public nNextUpdateAction NextAction; |
41 |
public NetSparkleConfiguration ApplicationConfig; |
42 |
public NetSparkleAppCastItem LatestVersion; |
43 |
} |
44 |
|
45 |
/// <summary> |
46 |
/// This delegate will be used when an update was detected to allow library |
47 |
/// consumer to add own user interface capabilities. |
48 |
/// </summary> |
49 |
/// <param name="sender"></param> |
50 |
/// <param name="e"></param> |
51 |
public delegate void UpdateDetected(Object sender, UpdateDetectedEventArgs e); |
52 |
|
53 |
public class Sparkle : IDisposable |
54 |
{ |
55 |
private BackgroundWorker _worker = new BackgroundWorker(); |
56 |
|
57 |
private String _AppCastUrl; |
58 |
private String _AppReferenceAssembly; |
59 |
|
60 |
private Boolean _DoInitialCheck; |
61 |
private Boolean _ForceInitialCheck; |
62 |
|
63 |
private EventWaitHandle _exitHandle; |
64 |
private EventWaitHandle _loopingHandle; |
65 |
|
66 |
private NetSparkleMainWindows _DiagnosticWindow; |
67 |
|
68 |
private TimeSpan _CheckFrequency; |
69 |
|
70 |
/// <summary> |
71 |
/// Enables system profiling against a profile server |
72 |
/// </summary> |
73 |
public Boolean EnableSystemProfiling = false; |
74 |
|
75 |
/// <summary> |
76 |
/// Hides the release notes view when an update was found. This |
77 |
/// mode is switched on automatically when no sparkle:releaseNotesLink |
78 |
/// tag was found in the app cast |
79 |
/// </summary> |
80 |
public Boolean HideReleaseNotes = false; |
81 |
|
82 |
/// <summary> |
83 |
/// Contains the profile url for System profiling |
84 |
/// </summary> |
85 |
public Uri SystemProfileUrl; |
86 |
|
87 |
/// <summary> |
88 |
/// This event will be raised when a check loop will be started |
89 |
/// </summary> |
90 |
public event LoopStartedOperation checkLoopStarted; |
91 |
|
92 |
/// <summary> |
93 |
/// This event will be raised when a check loop is finished |
94 |
/// </summary> |
95 |
public event LoopFinishedOperation checkLoopFinished; |
96 |
|
97 |
/// <summary> |
98 |
/// This event can be used to override the standard user interface |
99 |
/// process when an update is detected |
100 |
/// </summary> |
101 |
public event UpdateDetected updateDetected; |
102 |
|
103 |
/// <summary> |
104 |
/// This property holds an optional application icon |
105 |
/// which will be displayed in the software update dialog. The icon has |
106 |
/// to be 48x48 pixels. |
107 |
/// </summary> |
108 |
public Image ApplicationIcon { get; set; } |
109 |
|
110 |
/// <summary> |
111 |
/// This property returns an optional application icon |
112 |
/// which will displayed in the windows as self |
113 |
/// </summary> |
114 |
public Icon ApplicationWindowIcon { get; set; } |
115 |
|
116 |
/// <summary> |
117 |
/// This property enables a diagnostic window for debug reasons |
118 |
/// </summary> |
119 |
public Boolean ShowDiagnosticWindow { get; set; } |
120 |
|
121 |
/// <summary> |
122 |
/// This property enables the silent mode, this means |
123 |
/// the application will be updated without user interaction |
124 |
/// </summary> |
125 |
public Boolean EnableSilentMode { get; set; } |
126 |
|
127 |
/// <summary> |
128 |
/// This property returns true when the upadete loop is running |
129 |
/// and files when the loop is not running |
130 |
/// </summary> |
131 |
public Boolean IsUpdateLoopRunning |
132 |
{ |
133 |
get |
134 |
{ |
135 |
return _loopingHandle.WaitOne(0); |
136 |
} |
137 |
} |
138 |
|
139 |
/// <summary> |
140 |
/// This property defines if we trust every ssl connection also when |
141 |
/// this connection has not a valid cert |
142 |
/// </summary> |
143 |
public Boolean TrustEverySSLConnection { get; set; } |
144 |
|
145 |
/// <summary> |
146 |
/// ctor which needs the appcast url |
147 |
/// </summary> |
148 |
/// <param name="appcastUrl"></param> |
149 |
public Sparkle(String appcastUrl) |
150 |
: this(appcastUrl, null) |
151 |
{ } |
152 |
|
153 |
/// <summary> |
154 |
/// ctor which needs the appcast url and a referenceassembly |
155 |
/// </summary> |
156 |
public Sparkle(String appcastUrl, String referenceAssembly) |
157 |
: this(appcastUrl, referenceAssembly, false) |
158 |
{ } |
159 |
|
160 |
/// <summary> |
161 |
/// ctor which needs the appcast url and a referenceassembly |
162 |
/// </summary> |
163 |
public Sparkle(String appcastUrl, String referenceAssembly, Boolean ShowDiagnostic) |
164 |
{ |
165 |
// preconfige ssl trust |
166 |
TrustEverySSLConnection = false; |
167 |
|
168 |
// configure ssl cert link |
169 |
ServicePointManager.ServerCertificateValidationCallback += RemoteCertificateValidation; |
170 |
|
171 |
// enable visual style to ensure that we have XP style or higher |
172 |
// also in WPF applications |
173 |
System.Windows.Forms.Application.EnableVisualStyles(); |
174 |
|
175 |
// reset vars |
176 |
ApplicationIcon = null; |
177 |
_AppReferenceAssembly = null; |
178 |
|
179 |
// set var |
180 |
ShowDiagnosticWindow = ShowDiagnostic; |
181 |
|
182 |
// create the diagnotic window |
183 |
_DiagnosticWindow = new NetSparkleMainWindows(); |
184 |
|
185 |
// set the reference assembly |
186 |
if (referenceAssembly != null) |
187 |
{ |
188 |
_AppReferenceAssembly = referenceAssembly; |
189 |
_DiagnosticWindow.Report("Checking the following file: " + _AppReferenceAssembly); |
190 |
} |
191 |
|
192 |
// show if needed |
193 |
ShowDiagnosticWindowIfNeeded(); |
194 |
|
195 |
// adjust the delegates |
196 |
_worker.WorkerReportsProgress = true; |
197 |
_worker.DoWork += new DoWorkEventHandler(_worker_DoWork); |
198 |
_worker.ProgressChanged += new ProgressChangedEventHandler(_worker_ProgressChanged); |
199 |
|
200 |
// build the wait handle |
201 |
_exitHandle = new EventWaitHandle(false, EventResetMode.AutoReset); |
202 |
_loopingHandle = new EventWaitHandle(false, EventResetMode.ManualReset); |
203 |
|
204 |
// set the url |
205 |
_AppCastUrl = appcastUrl; |
206 |
_DiagnosticWindow.Report("Using the following url: " + _AppCastUrl); |
207 |
} |
208 |
|
209 |
/// <summary> |
210 |
/// The method starts a NetSparkle background loop |
211 |
/// If NetSparkle is configured to check for updates on startup, proceeds to perform |
212 |
/// the check. You should only call this function when your app is initialized and |
213 |
/// shows its main window. |
214 |
/// </summary> |
215 |
/// <param name="doInitialCheck"></param> |
216 |
public void StartLoop(Boolean doInitialCheck) |
217 |
{ |
218 |
StartLoop(doInitialCheck, false); |
219 |
} |
220 |
|
221 |
/// <summary> |
222 |
/// The method starts a NetSparkle background loop |
223 |
/// If NetSparkle is configured to check for updates on startup, proceeds to perform |
224 |
/// the check. You should only call this function when your app is initialized and |
225 |
/// shows its main window. |
226 |
/// </summary> |
227 |
/// <param name="doInitialCheck"></param> |
228 |
/// <param name="checkFrequency"></param> |
229 |
public void StartLoop(Boolean doInitialCheck, TimeSpan checkFrequency) |
230 |
{ |
231 |
StartLoop(doInitialCheck, false, checkFrequency); |
232 |
} |
233 |
|
234 |
/// <summary> |
235 |
/// The method starts a NetSparkle background loop |
236 |
/// If NetSparkle is configured to check for updates on startup, proceeds to perform |
237 |
/// the check. You should only call this function when your app is initialized and |
238 |
/// shows its main window. |
239 |
/// </summary> |
240 |
/// <param name="doInitialCheck"></param> |
241 |
/// <param name="forceInitialCheck"></param> |
242 |
public void StartLoop(Boolean doInitialCheck, Boolean forceInitialCheck) |
243 |
{ |
244 |
StartLoop(doInitialCheck, forceInitialCheck, TimeSpan.FromHours(24)); |
245 |
} |
246 |
|
247 |
/// <summary> |
248 |
/// The method starts a NetSparkle background loop |
249 |
/// If NetSparkle is configured to check for updates on startup, proceeds to perform |
250 |
/// the check. You should only call this function when your app is initialized and |
251 |
/// shows its main window. |
252 |
/// </summary> |
253 |
/// <param name="doInitialCheck"></param> |
254 |
/// <param name="forceInitialCheck"></param> |
255 |
/// <param name="checkFrequency"></param> |
256 |
public void StartLoop(Boolean doInitialCheck, Boolean forceInitialCheck, TimeSpan checkFrequency) |
257 |
{ |
258 |
// first set the event handle |
259 |
_loopingHandle.Set(); |
260 |
|
261 |
// Start the helper thread as a background worker to |
262 |
// get well ui interaction |
263 |
|
264 |
// show if needed |
265 |
ShowDiagnosticWindowIfNeeded(); |
266 |
|
267 |
// store infos |
268 |
_DoInitialCheck = doInitialCheck; |
269 |
_ForceInitialCheck = forceInitialCheck; |
270 |
_CheckFrequency = checkFrequency; |
271 |
|
272 |
// create and configure the worker |
273 |
_DiagnosticWindow.Report("Starting background worker"); |
274 |
|
275 |
// start the work |
276 |
_worker.RunWorkerAsync(); |
277 |
} |
278 |
|
279 |
/// <summary> |
280 |
/// This method will stop the sparkle background loop and is called |
281 |
/// through the disposable interface automatically |
282 |
/// </summary> |
283 |
public void StopLoop() |
284 |
{ |
285 |
// ensure the work will finished |
286 |
_exitHandle.Set(); |
287 |
} |
288 |
|
289 |
/// <summary> |
290 |
/// Is called in the using context and will stop all background activities |
291 |
/// </summary> |
292 |
public void Dispose() |
293 |
{ |
294 |
StopLoop(); |
295 |
} |
296 |
|
297 |
/// <summary> |
298 |
/// This method updates the profile information which can be sended to the server if enabled |
299 |
/// </summary> |
300 |
/// <param name="config"></param> |
301 |
public void UpdateSystemProfileInformation(NetSparkleConfiguration config) |
302 |
{ |
303 |
// check if profile data is enabled |
304 |
if (!EnableSystemProfiling) |
305 |
return; |
306 |
|
307 |
// check if we need an update |
308 |
if (DateTime.Now - config.LastProfileUpdate < new TimeSpan(7, 0, 0, 0)) |
309 |
return; |
310 |
|
311 |
// touch the profile update time |
312 |
config.TouchProfileTime(); |
313 |
|
314 |
// start the profile thread |
315 |
Thread t = new Thread(ProfileDataThreadStart); |
316 |
t.Start(config); |
317 |
} |
318 |
|
319 |
/// <summary> |
320 |
/// Profile data thread |
321 |
/// </summary> |
322 |
/// <param name="obj"></param> |
323 |
private void ProfileDataThreadStart(object obj) |
324 |
{ |
325 |
try |
326 |
{ |
327 |
if (SystemProfileUrl != null) |
328 |
{ |
329 |
// get the config |
330 |
NetSparkleConfiguration config = obj as NetSparkleConfiguration; |
331 |
|
332 |
// collect data |
333 |
NetSparkleDeviceInventory inv = new NetSparkleDeviceInventory(config); |
334 |
inv.CollectInventory(); |
335 |
|
336 |
// build url |
337 |
String requestUrl = inv.BuildRequestUrl(SystemProfileUrl.ToString() + "?"); |
338 |
|
339 |
HttpWebRequest.DefaultWebProxy = HttpWebRequest.GetSystemWebProxy(); |
340 |
|
341 |
// perform the webrequest |
342 |
HttpWebRequest request = HttpWebRequest.Create(requestUrl) as HttpWebRequest; |
343 |
using (WebResponse response = request.GetResponse()) |
344 |
{ |
345 |
// close the response |
346 |
response.Close(); |
347 |
} |
348 |
} |
349 |
} |
350 |
catch (Exception ex) |
351 |
{ |
352 |
// No exception during data send |
353 |
ReportDiagnosticMessage(ex.Message); |
354 |
} |
355 |
} |
356 |
|
357 |
/// <summary> |
358 |
/// This method checks if an update is required. During this process the appcast |
359 |
/// will be downloaded and checked against the reference assembly. Ensure that |
360 |
/// the calling process has access to the internet and read access to the |
361 |
/// reference assembly. This method is also called from the background loops. |
362 |
/// </summary> |
363 |
/// <param name="config"></param> |
364 |
/// <returns></returns> |
365 |
public Boolean IsUpdateRequired(NetSparkleConfiguration config, out NetSparkleAppCastItem latestVersion) |
366 |
{ |
367 |
// report |
368 |
ReportDiagnosticMessage("Downloading and checking appcast"); |
369 |
|
370 |
// init the appcast |
371 |
NetSparkleAppCast cast = new NetSparkleAppCast(_AppCastUrl, config); |
372 |
|
373 |
// check if any updates are available |
374 |
try |
375 |
{ |
376 |
latestVersion = cast.GetLatestVersion(); |
377 |
} |
378 |
catch (Exception e) |
379 |
{ |
380 |
// show the exeception message |
381 |
ReportDiagnosticMessage("Error during app cast download: " + e.Message); |
382 |
|
383 |
// just null the version info |
384 |
latestVersion = null; |
385 |
} |
386 |
|
387 |
if (latestVersion == null) |
388 |
{ |
389 |
ReportDiagnosticMessage("No version information in app cast found"); |
390 |
return false; |
391 |
} |
392 |
else |
393 |
{ |
394 |
ReportDiagnosticMessage("Lastest version on the server is " + latestVersion.Version); |
395 |
} |
396 |
|
397 |
// set the last check time |
398 |
ReportDiagnosticMessage("Touch the last check timestamp"); |
399 |
config.TouchCheckTime(); |
400 |
|
401 |
// check if the available update has to be skipped |
402 |
if (latestVersion.Version.Equals(config.SkipThisVersion)) |
403 |
{ |
404 |
ReportDiagnosticMessage("Latest update has to be skipped (user decided to skip version " + config.SkipThisVersion + ")"); |
405 |
return false; |
406 |
} |
407 |
|
408 |
// check if the version will be the same then the installed version |
409 |
Version v1 = new Version(config.InstalledVersion); |
410 |
Version v2 = new Version(latestVersion.Version); |
411 |
|
412 |
if (v2 <= v1) |
413 |
{ |
414 |
ReportDiagnosticMessage("Installed version is valid, no update needed (" + config.InstalledVersion + ")"); |
415 |
return false; |
416 |
} |
417 |
|
418 |
// ok we need an update |
419 |
return true; |
420 |
} |
421 |
|
422 |
/// <summary> |
423 |
/// This method reads the local sparkle configuration for the given |
424 |
/// reference assembly |
425 |
/// </summary> |
426 |
/// <param name="AppReferenceAssembly"></param> |
427 |
/// <returns></returns> |
428 |
public NetSparkleConfiguration GetApplicationConfig() |
429 |
{ |
430 |
NetSparkleConfiguration config; |
431 |
config = new NetSparkleConfiguration(_AppReferenceAssembly); |
432 |
return config; |
433 |
} |
434 |
|
435 |
/// <summary> |
436 |
/// This method shows the update ui and allows to perform the |
437 |
/// update process |
438 |
/// </summary> |
439 |
/// <param name="currentItem"></param> |
440 |
public void ShowUpdateNeededUI(NetSparkleAppCastItem currentItem) |
441 |
{ |
442 |
|
443 |
// create the form |
444 |
NetSparkleForm frm = new NetSparkleForm(currentItem, ApplicationIcon, ApplicationWindowIcon); |
445 |
|
446 |
// configure the form |
447 |
frm.TopMost = true; |
448 |
|
449 |
if (HideReleaseNotes) |
450 |
frm.RemoveReleaseNotesControls(); |
451 |
|
452 |
|
453 |
// show it |
454 |
DialogResult dlgResult = frm.ShowDialog(); |
455 |
|
456 |
|
457 |
if (dlgResult == DialogResult.No) |
458 |
{ |
459 |
// skip this version |
460 |
NetSparkleConfiguration config = new NetSparkleConfiguration(_AppReferenceAssembly); |
461 |
config.SetVersionToSkip(currentItem.Version); |
462 |
} |
463 |
else if (dlgResult == DialogResult.Yes) |
464 |
{ |
465 |
// download the binaries |
466 |
InitDownloadAndInstallProcess(currentItem); |
467 |
} |
468 |
|
469 |
} |
470 |
|
471 |
/// <summary> |
472 |
/// This method reports a message in the diagnostic window |
473 |
/// </summary> |
474 |
/// <param name="message"></param> |
475 |
public void ReportDiagnosticMessage(String message) |
476 |
{ |
477 |
if (_DiagnosticWindow.InvokeRequired) |
478 |
{ |
479 |
_DiagnosticWindow.Invoke(new Action<String>(ReportDiagnosticMessage), message); |
480 |
} |
481 |
else |
482 |
{ |
483 |
_DiagnosticWindow.Report(message); |
484 |
} |
485 |
} |
486 |
|
487 |
/// <summary> |
488 |
/// This method will be executed as worker thread |
489 |
/// </summary> |
490 |
/// <param name="sender"></param> |
491 |
/// <param name="e"></param> |
492 |
void _worker_DoWork(object sender, DoWorkEventArgs e) |
493 |
{ |
494 |
// store the did run once feature |
495 |
Boolean goIntoLoop = true; |
496 |
Boolean checkTSP = true; |
497 |
Boolean doInitialCheck = _DoInitialCheck; |
498 |
Boolean isInitialCheck = true; |
499 |
|
500 |
// start our lifecycles |
501 |
do |
502 |
{ |
503 |
// set state |
504 |
Boolean bUpdateRequired = false; |
505 |
|
506 |
// notify |
507 |
if (checkLoopStarted != null) |
508 |
checkLoopStarted(this); |
509 |
|
510 |
// report status |
511 |
if (doInitialCheck == false) |
512 |
{ |
513 |
ReportDiagnosticMessage("Initial check prohibited, going to wait"); |
514 |
doInitialCheck = true; |
515 |
goto WaitSection; |
516 |
} |
517 |
|
518 |
// report status |
519 |
ReportDiagnosticMessage("Starting update loop..."); |
520 |
|
521 |
// read the config |
522 |
ReportDiagnosticMessage("Reading config..."); |
523 |
NetSparkleConfiguration config = GetApplicationConfig(); |
524 |
|
525 |
// calc CheckTasp |
526 |
Boolean checkTSPInternal = checkTSP; |
527 |
|
528 |
if (isInitialCheck && checkTSPInternal) |
529 |
checkTSPInternal = !_ForceInitialCheck; |
530 |
|
531 |
// check if it's ok the recheck to software state |
532 |
if (checkTSPInternal) |
533 |
{ |
534 |
TimeSpan csp = DateTime.Now - config.LastCheckTime; |
535 |
if (csp < _CheckFrequency) |
536 |
{ |
537 |
ReportDiagnosticMessage(String.Format("Update check performed within the last {0} minutes!", _CheckFrequency.TotalMinutes)); |
538 |
goto WaitSection; |
539 |
} |
540 |
} |
541 |
else |
542 |
checkTSP = true; |
543 |
|
544 |
// when sparkle will be deactivated wait an other cycle |
545 |
if (config.CheckForUpdate == false) |
546 |
{ |
547 |
ReportDiagnosticMessage("Check for updates disabled"); |
548 |
goto WaitSection; |
549 |
} |
550 |
|
551 |
// update the runonce feature |
552 |
goIntoLoop = !config.DidRunOnce; |
553 |
|
554 |
// update profile information is needed |
555 |
UpdateSystemProfileInformation(config); |
556 |
|
557 |
// check if update is required |
558 |
NetSparkleAppCastItem latestVersion = null; |
559 |
bUpdateRequired = IsUpdateRequired(config, out latestVersion); |
560 |
if (!bUpdateRequired) |
561 |
goto WaitSection; |
562 |
|
563 |
// show the update window |
564 |
ReportDiagnosticMessage("Update needed from version " + config.InstalledVersion + " to version " + latestVersion.Version); |
565 |
|
566 |
// send notification if needed |
567 |
UpdateDetectedEventArgs ev = new UpdateDetectedEventArgs() { NextAction = nNextUpdateAction.showStandardUserInterface, ApplicationConfig = config, LatestVersion = latestVersion }; |
568 |
if (updateDetected != null) |
569 |
updateDetected(this, ev); |
570 |
|
571 |
// check results |
572 |
switch(ev.NextAction) |
573 |
{ |
574 |
case nNextUpdateAction.performUpdateUnattended: |
575 |
{ |
576 |
ReportDiagnosticMessage("Unattended update whished from consumer"); |
577 |
EnableSilentMode = true; |
578 |
_worker.ReportProgress(1, latestVersion); |
579 |
break; |
580 |
} |
581 |
case nNextUpdateAction.prohibitUpdate: |
582 |
{ |
583 |
ReportDiagnosticMessage("Update prohibited from consumer"); |
584 |
break; |
585 |
} |
586 |
case nNextUpdateAction.showStandardUserInterface: |
587 |
default: |
588 |
{ |
589 |
ReportDiagnosticMessage("Standard UI update whished from consumer"); |
590 |
_worker.ReportProgress(1, latestVersion); |
591 |
break; |
592 |
} |
593 |
} |
594 |
|
595 |
WaitSection: |
596 |
// reset initialcheck |
597 |
isInitialCheck = false; |
598 |
|
599 |
// notify |
600 |
if (checkLoopFinished != null) |
601 |
checkLoopFinished(this, bUpdateRequired); |
602 |
|
603 |
// report wait statement |
604 |
ReportDiagnosticMessage(String.Format("Sleeping for an other {0} minutes, exit event or force update check event", _CheckFrequency.TotalMinutes)); |
605 |
|
606 |
// wait for |
607 |
if (!goIntoLoop) |
608 |
break; |
609 |
else |
610 |
{ |
611 |
// build the event array |
612 |
WaitHandle[] handles = new WaitHandle[1]; |
613 |
handles[0] = _exitHandle; |
614 |
|
615 |
// wait for any |
616 |
int i = WaitHandle.WaitAny(handles, _CheckFrequency); |
617 |
if (WaitHandle.WaitTimeout == i) |
618 |
{ |
619 |
ReportDiagnosticMessage(String.Format("{0} minutes are over", _CheckFrequency.TotalMinutes)); |
620 |
continue; |
621 |
} |
622 |
|
623 |
// check the exit hadnle |
624 |
if (i == 0) |
625 |
{ |
626 |
ReportDiagnosticMessage("Got exit signal"); |
627 |
break; |
628 |
} |
629 |
|
630 |
// check an other check needed |
631 |
if (i == 1) |
632 |
{ |
633 |
ReportDiagnosticMessage("Got force update check signal"); |
634 |
checkTSP = false; |
635 |
continue; |
636 |
} |
637 |
} |
638 |
} while (goIntoLoop); |
639 |
|
640 |
// reset the islooping handle |
641 |
_loopingHandle.Reset(); |
642 |
} |
643 |
|
644 |
/// <summary> |
645 |
/// This method will be notified |
646 |
/// </summary> |
647 |
/// <param name="sender"></param> |
648 |
/// <param name="e"></param> |
649 |
private void _worker_ProgressChanged(object sender, ProgressChangedEventArgs e) |
650 |
{ |
651 |
switch (e.ProgressPercentage) |
652 |
{ |
653 |
case 1: |
654 |
{ |
655 |
// get the current item |
656 |
NetSparkleAppCastItem currentItem = e.UserState as NetSparkleAppCastItem; |
657 |
|
658 |
// show the update ui |
659 |
if (EnableSilentMode == true) |
660 |
InitDownloadAndInstallProcess(currentItem); |
661 |
else |
662 |
ShowUpdateNeededUI(currentItem); |
663 |
|
664 |
break; |
665 |
} |
666 |
case 0: |
667 |
{ |
668 |
ReportDiagnosticMessage(e.UserState.ToString()); |
669 |
break; |
670 |
} |
671 |
} |
672 |
} |
673 |
|
674 |
private void InitDownloadAndInstallProcess(NetSparkleAppCastItem item) |
675 |
{ |
676 |
NetSparkleDownloadProgress dlProgress = new NetSparkleDownloadProgress(this, item, _AppReferenceAssembly, ApplicationIcon, ApplicationWindowIcon, EnableSilentMode); |
677 |
dlProgress.ShowDialog(); |
678 |
} |
679 |
|
680 |
private void ShowDiagnosticWindowIfNeeded() |
681 |
{ |
682 |
if (_DiagnosticWindow.InvokeRequired) |
683 |
{ |
684 |
_DiagnosticWindow.Invoke(new Action(ShowDiagnosticWindowIfNeeded)); |
685 |
} |
686 |
else |
687 |
{ |
688 |
// check the diagnotic value |
689 |
NetSparkleConfiguration config = new NetSparkleConfiguration(_AppReferenceAssembly); |
690 |
if (config.ShowDiagnosticWindow || ShowDiagnosticWindow) |
691 |
{ |
692 |
Point newLocation = new Point(); |
693 |
|
694 |
newLocation.X = Screen.PrimaryScreen.Bounds.Width - _DiagnosticWindow.Width; |
695 |
newLocation.Y = 0; |
696 |
|
697 |
_DiagnosticWindow.Location = newLocation; |
698 |
_DiagnosticWindow.Show(); |
699 |
} |
700 |
} |
701 |
} |
702 |
|
703 |
private bool RemoteCertificateValidation(object sender, X509Certificate certificate, X509Chain chain, SslPolicyErrors sslPolicyErrors) |
704 |
{ |
705 |
if (TrustEverySSLConnection) |
706 |
{ |
707 |
// verify if we talk about our app cast dll |
708 |
HttpWebRequest req = sender as HttpWebRequest; |
709 |
if (req == null) |
710 |
return (certificate is X509Certificate2) ? ((X509Certificate2)certificate).Verify() : false; |
711 |
|
712 |
// if so just return our trust |
713 |
if (req.RequestUri.Equals(new Uri(_AppCastUrl))) |
714 |
return true; |
715 |
else |
716 |
return (certificate is X509Certificate2) ? ((X509Certificate2)certificate).Verify() : false; |
717 |
} |
718 |
else |
719 |
{ |
720 |
// check our cert |
721 |
return (certificate is X509Certificate2) ? ((X509Certificate2)certificate).Verify() : false; |
722 |
} |
723 |
} |
724 |
} |
725 |
} |