Updater.cs
上传用户:hbhltzc
上传日期:2022-06-04
资源大小:1925k
文件大小:9k
源码类别:

xml/soap/webservice

开发平台:

Visual C++

  1. using System;
  2. using System.Text;
  3. using System.Xml;
  4. using System.Windows.Forms;
  5. using System.Threading;
  6. using System.Diagnostics;
  7. using System.Net;
  8. using System.IO;
  9. using System.Collections.Generic;
  10. namespace XmlNotepad {
  11.     class Updater : IDisposable {
  12.         Settings settings;
  13.         DateTime lastCheck = DateTime.MinValue;
  14.         TimeSpan updateFrequency = TimeSpan.MaxValue;
  15.         Uri updateUri;
  16.         System.Windows.Forms.Timer timer;
  17.         string download;
  18.         string title;
  19.         string version;
  20.         bool enabled = true;
  21.         WebRequest req;
  22.         bool disposed;
  23.         TimeSpan MinimumUpdateFrequency = TimeSpan.FromSeconds(5);
  24.         public event EventHandler UpdateRequired;
  25.         public Updater(Settings s){
  26.             this.settings = s;
  27.             s["LastUpdateCheck"] = lastCheck;
  28.             s["UpdateFrequency"] = updateFrequency;
  29.             s["UpdateLocation"] = "";
  30.             s["UpdateEnabled"] = enabled;
  31.             s.Changed += new SettingsEventHandler(OnSettingChanged);
  32.             StartTimer(5000); // give time for process to start & load
  33.         }
  34.         void StartTimer() {
  35.             if (this.updateFrequency != TimeSpan.MaxValue) {
  36.                 StartTimer((int)this.updateFrequency.TotalMilliseconds);
  37.             }
  38.         }
  39.         void StartTimer(int interval) {
  40.             StopTimer();
  41.             if (this.enabled && !this.disposed) {
  42.                 timer = new System.Windows.Forms.Timer();
  43.                 timer.Interval = interval;
  44.                 timer.Tick += new EventHandler(OnTimerTick);
  45.                 timer.Start();
  46.             }
  47.         }
  48.         void StopTimer() {
  49.             using (timer) {
  50.                 if (timer != null) 
  51.                     timer.Stop();
  52.             }
  53.             this.timer = null;
  54.         }
  55.         public string DownloadPage { get { return this.download; } }
  56.         public string Title { get { return this.title; } set { this.title = value; } }
  57.         public string Version { get { return this.version; } set { this.version = value; } }
  58.         void OnSettingChanged(object sender, string name) {
  59.             switch (name) {
  60.                 case "LastUpdateCheck":
  61.                     this.lastCheck = (DateTime)settings["LastUpdateCheck"];
  62.                     break;
  63.                 case "UpdateFrequency":
  64.                     SetUpdateFrequency((TimeSpan)settings["UpdateFrequency"]);
  65.                     break;
  66.                 case "UpdateLocation":
  67.                     SetUpdateLocation((string)settings["UpdateLocation"]);                    
  68.                     break;
  69.                 case "UpdateEnabled":
  70.                     SetEnabled((bool)settings["UpdateEnabled"]);
  71.                     break;
  72.             }
  73.         }
  74.         void SetEnabled(bool e) {
  75.             if (this.enabled != e) {
  76.                 this.enabled = e;
  77.                 if (e && !this.disposed) {
  78.                     StartTimer();
  79.                 } else {
  80.                     StopTimer();
  81.                 }
  82.             }
  83.         }
  84.         void SetUpdateFrequency(TimeSpan ts) {
  85.             if (ts == TimeSpan.MaxValue || ts < MinimumUpdateFrequency) {
  86.                 ts = MinimumUpdateFrequency;
  87.             }
  88.             this.updateFrequency = ts;
  89.             TimeSpan f = (TimeSpan)settings["UpdateFrequency"];
  90.             if (f != ts) {
  91.                 settings["UpdateFrequency"] = ts;
  92.             }
  93.             StartTimer((int)ts.TotalMilliseconds);
  94.         }
  95.         void SetUpdateLocation(string location) {
  96.             if (string.IsNullOrEmpty(location)) return;
  97.             Uri uri = new Uri(location);
  98.             if (uri != this.updateUri) {                
  99.                 this.updateUri = uri;
  100.                 if ((string)settings["UpdateLocation"] != location) {
  101.                     settings["UpdateLocation"] = location;
  102.                 }
  103.                 // Location has just changed, so we need to download the new update information.
  104.                 StartTimer();
  105.             }
  106.         }
  107.         public void OnUserChange(string oldUri) {
  108.             if ((string)settings["UpdateLocation"] != oldUri) {
  109.                 // then this user changed the location, so we need to ping the new
  110.                 // location right away.
  111.                 this.lastCheck = DateTime.MinValue;
  112.                 StartTimer(1000);
  113.             }
  114.         }
  115.         
  116.         void OnTimerTick(object sender, EventArgs e) {
  117.             StopTimer();
  118.             if (this.updateUri == null) {
  119.                 Bootstrap();
  120.             } else if (this.lastCheck == DateTime.MinValue ||
  121.                 this.updateFrequency == TimeSpan.MaxValue ||
  122.                 this.lastCheck + this.updateFrequency < DateTime.Now) {
  123.                 ThreadPool.QueueUserWorkItem(new WaitCallback(CheckForUpdate));
  124.             }
  125.         }
  126.         void CheckForUpdate(object state) {
  127.             if (this.updateUri != null) {
  128.                 try {
  129.                     // assume success in this request so we don't create DOS attacks on the server!
  130.                     this.lastCheck = DateTime.Now;
  131.                     settings["LastUpdateCheck"] = this.lastCheck;
  132.                     // now check
  133.                     WebRequest wr = WebRequest.Create(this.updateUri);
  134.                     this.req = wr;
  135.                     wr.Credentials = CredentialCache.DefaultCredentials;
  136.                     wr.Proxy = WebRequest.DefaultWebProxy;
  137.                     WebResponse r = wr.GetResponse();
  138.                     XmlDocument doc = null;
  139.                     using (Stream s = r.GetResponseStream()) {
  140.                         doc = new XmlDocument();
  141.                         doc.Load(s);
  142.                     }
  143.                     if (!this.disposed) {
  144.                         ProcessUpdate(doc);
  145.                     }
  146.                 } catch (Exception) {
  147.                     StartTimer();
  148.                 } finally {
  149.                     this.req = null;
  150.                 }
  151.             }
  152.         }
  153.         void Bootstrap() {
  154.             // See if we can find a local copy of updates.xml so that we can bootstrap the
  155.             // location from there.
  156.             Uri baseUri = new Uri(this.GetType().Assembly.Location);
  157.             Uri resolved = new Uri(baseUri, "updates.xml");
  158.             string file = resolved.LocalPath;
  159.             if (File.Exists(file)) {
  160.                 try {
  161.                     XmlDocument doc = new XmlDocument();
  162.                     doc.Load(file);
  163.                     ProcessUpdate(doc);
  164.                 } catch (Exception e) {
  165.                     Trace.WriteLine(e.Message);
  166.                 }
  167.             }
  168.         }
  169.         void ProcessUpdate(XmlDocument doc) {
  170.             Version v = GetType().Assembly.GetName().Version;
  171.             string ver = v.ToString();
  172.             XmlElement loc = doc.SelectSingleNode("updates/application/location") as XmlElement;
  173.             if (loc != null) {
  174.                 try {
  175.                     Uri uri = new Uri(loc.InnerText);
  176.                     if (uri != this.updateUri) {
  177.                         string location = uri.IsFile ? uri.LocalPath : uri.AbsoluteUri;
  178.                         SetUpdateLocation(location);
  179.                         return; // page has been moved - start over!
  180.                     }
  181.                 } catch (Exception e) {
  182.                     Trace.WriteLine(e.Message);
  183.                 }
  184.             }
  185.             XmlElement de = doc.SelectSingleNode("updates/application/download") as XmlElement;
  186.             if (de != null) {
  187.                 this.download = de.InnerText;
  188.             }
  189.             XmlElement f = doc.SelectSingleNode("updates/application/frequency") as XmlElement;
  190.             if (f != null) {
  191.                 try {
  192.                     SetUpdateFrequency(TimeSpan.Parse(f.InnerText));
  193.                 } catch (Exception ex) {
  194.                     Trace.WriteLine(ex.Message);
  195.                 }
  196.             }
  197.             bool newVersion = false;
  198.             foreach (XmlElement e in doc.SelectNodes("updates/version")) {
  199.                 string n = e.GetAttribute("number");
  200.                 if (!string.IsNullOrEmpty(n)) {
  201.                     Version v2 = new Version(n);
  202.                     if (v2 > v) {
  203.                         // new version is available!
  204.                         this.version = n;
  205.                         newVersion = true;
  206.                         break;
  207.                     }
  208.                 }
  209.             }
  210.             if (newVersion && this.UpdateRequired != null) {
  211.                 this.UpdateRequired(this, EventArgs.Empty);
  212.             }
  213.         }
  214.         public void Dispose() {
  215.             this.disposed = true;
  216.             StopTimer();
  217.             WebRequest r = this.req;
  218.             if (r != null) {
  219.                 try {
  220.                     r.Abort();
  221.                 } catch {
  222.                 }
  223.             }            
  224.         }
  225.      
  226.     }
  227. }