Added NetSparkle for auto updating
[pithos-ms-client] / trunk / NetSparkle / NetSparkleConfiguration.cs
1 using System;
2 using System.Collections.Generic;
3 using System.Linq;
4 using System.Text;
5 using Microsoft.Win32;
6 using System.Diagnostics;
7
8 namespace AppLimit.NetSparkle
9 {
10     /// <summary>
11     /// This class handles all registry values which are used from sparkle to handle 
12     /// update intervalls. All values are stored in HKCU\Software\Vendor\AppName which 
13     /// will be read ot from the assembly information. All values are of the REG_SZ 
14     /// type, no matter what their "logical" type is. The following options are
15     /// available:
16     /// 
17     /// CheckForUpdate  - Boolean    - Whether NetSparkle should check for updates
18     /// LastCheckTime   - time_t     - Time of last check
19     /// SkipThisVersion - String     - If the user skipped an update, then the version to ignore is stored here (e.g. "1.4.3")
20     /// DidRunOnce      - Boolean    - Check only one time when the app launched
21     /// </summary>    
22     public class NetSparkleConfiguration
23     {
24         public String   ApplicationName     { get; private set; }
25         public String   InstalledVersion    { get; private set; }
26         public Boolean  CheckForUpdate      { get; private set; }
27         public DateTime LastCheckTime       { get; private set; }
28         public String   SkipThisVersion     { get; private set; }
29         public Boolean  DidRunOnce           { get; private set; }
30         public Boolean ShowDiagnosticWindow { get; private set; }
31         public DateTime LastProfileUpdate   { get; private set; }
32
33         /// <summary>
34         /// If this property is true a reflection based accessor will be used
35         /// to determine the assmebly name and verison, otherwise a System.Diagnostics
36         /// based access will be used
37         /// </summary>
38         public Boolean UseReflectionBasedAssemblyAccessor { get; private set; }
39
40         private String _referenceAssembly;
41
42         /// <summary>
43         /// The constructor reads out all configured values
44         /// </summary>        
45         public NetSparkleConfiguration(String ReferenceAssembly)
46             : this(ReferenceAssembly, true)
47         { }
48
49         public NetSparkleConfiguration(String ReferenceAssembly, Boolean UseReflectionBasedAssemblyAccessor)
50         {
51             // set the value
52             this.UseReflectionBasedAssemblyAccessor = UseReflectionBasedAssemblyAccessor;
53
54             // save the referecne assembly
55             _referenceAssembly = ReferenceAssembly;
56
57             try
58             {
59                 // set default values
60                 InitWithDefaultValues();
61
62                 // set some value from the binary
63                 NetSparkleAssemblyAccessor accessor = new NetSparkleAssemblyAccessor(ReferenceAssembly, this.UseReflectionBasedAssemblyAccessor);
64                 ApplicationName     = accessor.AssemblyProduct;
65                 InstalledVersion    = accessor.AssemblyVersion;
66
67                 // build the reg path
68                 String regPath = BuildRegistryPath();
69
70                 // load the values
71                 LoadValuesFromPath(regPath);                                
72             }
73             catch (Exception e)
74             {
75                 // disable update checks when exception was called 
76                 CheckForUpdate = false;
77
78                 if (e.Message.Contains("STOP:"))
79                     throw e;
80             }
81         }
82
83         /// <summary>
84         /// Touches to profile time
85         /// </summary>
86         public void TouchProfileTime()
87         {
88             // set the prodilt update time
89             LastProfileUpdate = DateTime.Now;
90
91             // build path
92             String path = BuildRegistryPath();
93
94             // save the values
95             SaveValuesToPath(path);
96         }
97
98         /// <summary>
99         /// Touches the check time to now, should be used after a check directly
100         /// </summary>
101         public void TouchCheckTime()
102         {
103             // set the check tiem
104             LastCheckTime = DateTime.Now;
105
106             // build path
107             String path = BuildRegistryPath();
108
109             // save the values
110             SaveValuesToPath(path);
111         }
112
113         /// <summary>
114         /// This method allows to skip a specific version
115         /// </summary>
116         /// <param name="version"></param>
117         public void SetVersionToSkip(String version)
118         {
119             // set the check tiem
120             SkipThisVersion = version;
121
122             // build path
123             String path = BuildRegistryPath();
124
125             // save the values
126             SaveValuesToPath(path);
127         }
128
129         /// <summary>
130         /// This function build a valid registry path in dependecy to the 
131         /// assembly information
132         /// </summary>
133         /// <returns></returns>
134         private String BuildRegistryPath()
135         {
136             NetSparkleAssemblyAccessor accessor = new NetSparkleAssemblyAccessor(_referenceAssembly, UseReflectionBasedAssemblyAccessor);
137
138             if (accessor.AssemblyCompany == null || accessor.AssemblyCompany.Length == 0 ||
139                     accessor.AssemblyProduct == null || accessor.AssemblyProduct.Length == 0)
140                 throw new Exception("STOP: Sparkle is missing the company or productname tag in " + _referenceAssembly);
141             
142             return "Software\\" + accessor.AssemblyCompany + "\\" + accessor.AssemblyProduct + "\\AutoUpdate";
143         }
144
145         /// <summary>
146         /// This method set's default values for the config
147         /// </summary>
148         private void InitWithDefaultValues()
149         {
150             CheckForUpdate = true;
151             LastCheckTime = new DateTime(0);
152             SkipThisVersion = String.Empty;
153             DidRunOnce = false;
154             UseReflectionBasedAssemblyAccessor = true;
155         }
156
157         /// <summary>
158         /// This method loads the values from registry
159         /// </summary>
160         /// <param name="regPath"></param>
161         /// <returns></returns>
162         private Boolean LoadValuesFromPath(String regPath)
163         {
164             RegistryKey key = Registry.CurrentUser.OpenSubKey(regPath);
165             if (key == null)
166                 return false;
167             else
168             {                
169                 // read out                
170                 String strCheckForUpdate = key.GetValue("CheckForUpdate", "True") as String;
171                 String strLastCheckTime = key.GetValue("LastCheckTime", new DateTime(0).ToString()) as String;
172                 String strSkipThisVersion = key.GetValue("SkipThisVersion", "") as String;                
173                 String strDidRunOnc = key.GetValue("DidRunOnce", "False") as String;
174                 String strShowDiagnosticWindow = key.GetValue("ShowDiagnosticWindow", "False") as String;
175                 String strProfileTime = key.GetValue("LastProfileUpdate", new DateTime(0).ToString()) as String;                
176
177                 // convert th right datatypes
178                 CheckForUpdate = Convert.ToBoolean(strCheckForUpdate);
179                 LastCheckTime = Convert.ToDateTime(strLastCheckTime);
180                 SkipThisVersion = strSkipThisVersion;
181                 DidRunOnce = Convert.ToBoolean(strDidRunOnc);
182                 ShowDiagnosticWindow = Convert.ToBoolean(strShowDiagnosticWindow);
183                 LastProfileUpdate = Convert.ToDateTime(strProfileTime);                
184                 return true;
185             }
186         }
187
188         /// <summary>
189         /// This method store the information into registry
190         /// </summary>
191         /// <param name="regPath"></param>
192         /// <returns></returns>
193         private Boolean SaveValuesToPath(String regPath)
194         {
195             RegistryKey key = Registry.CurrentUser.CreateSubKey(regPath);
196             if (key == null)
197                 return false;
198             else
199             {
200                 // convert to regsz
201                 String strCheckForUpdate    = CheckForUpdate.ToString();
202                 String strLastCheckTime     = LastCheckTime.ToString();
203                 String strSkipThisVersion   = SkipThisVersion.ToString();
204                 String strDidRunOnc         = DidRunOnce.ToString();
205                 String strProfileTime       = LastProfileUpdate.ToString();                
206
207                 // set the values
208                 key.SetValue("CheckForUpdate", strCheckForUpdate, RegistryValueKind.String);
209                 key.SetValue("LastCheckTime", strLastCheckTime, RegistryValueKind.String);
210                 key.SetValue("SkipThisVersion", strSkipThisVersion, RegistryValueKind.String);
211                 key.SetValue("DidRunOnce", strDidRunOnc, RegistryValueKind.String);
212                 key.SetValue("LastProfileUpdate", strProfileTime, RegistryValueKind.String);                
213
214                 return true;
215             }
216         }
217
218     }
219 }