markus / MarkusAutoUpdate / src / NetSparkle / Configurations / JSONConfiguration.cs @ 1f112f94
이력 | 보기 | 이력해설 | 다운로드 (8.21 KB)
1 | d8f5045e | taeseongkim | using NetSparkleUpdater.AssemblyAccessors; |
---|---|---|---|
2 | using NetSparkleUpdater.Interfaces; |
||
3 | #if NETFRAMEWORK |
||
4 | using Newtonsoft.Json; |
||
5 | #endif |
||
6 | using System; |
||
7 | using System.Collections.Generic; |
||
8 | using System.Globalization; |
||
9 | using System.IO; |
||
10 | using System.Text; |
||
11 | #if NETSTANDARD |
||
12 | using System.Text.Json; |
||
13 | #endif |
||
14 | |||
15 | namespace NetSparkleUpdater.Configurations |
||
16 | { |
||
17 | class JSONConfiguration : Configuration |
||
18 | { |
||
19 | private string _savePath; |
||
20 | |||
21 | /// <summary> |
||
22 | /// Constructor for a configuration that saves and loads its configuration data to and |
||
23 | /// from a JSON file that resides on disk. This Configuration can be used on any |
||
24 | /// operating system. |
||
25 | /// </summary> |
||
26 | /// <param name="assemblyAccessor">Object that accesses version, title, etc. info for the application |
||
27 | /// you would like to check for updates for</param> |
||
28 | public JSONConfiguration(IAssemblyAccessor assemblyAccessor) |
||
29 | : this(assemblyAccessor, string.Empty) |
||
30 | { } |
||
31 | |||
32 | /// <summary> |
||
33 | /// Constructor for a configuration that saves and loads its configuration data to and |
||
34 | /// from a JSON file that resides on disk. This Configuration can be used on any |
||
35 | /// operating system. |
||
36 | /// </summary> |
||
37 | /// <param name="assemblyAccessor">Object that accesses version, title, etc. info for the application |
||
38 | /// you would like to check for updates for</param> |
||
39 | /// <param name="savePath">location to save the JSON configuration data to; can be null or empty string. |
||
40 | /// If not null or empty string, must represent a valid path on disk (directories must already be created). |
||
41 | /// This class will take care of creating/overwriting the file at that path if necessary.</param> |
||
42 | public JSONConfiguration(IAssemblyAccessor assemblyAccessor, string savePath) |
||
43 | : base(assemblyAccessor) |
||
44 | { |
||
45 | _savePath = savePath != null && string.IsNullOrWhiteSpace(savePath) ? savePath : GetSavePath(); |
||
46 | try |
||
47 | { |
||
48 | // get the save path |
||
49 | _savePath = GetSavePath(); |
||
50 | // load the values |
||
51 | LoadValuesFromPath(_savePath); |
||
52 | } |
||
53 | catch (NetSparkleException e) |
||
54 | { |
||
55 | // disable update checks when exception occurred -- can't read/save necessary update file |
||
56 | CheckForUpdate = false; |
||
57 | throw new NetSparkleException("Can't read/save configuration data: " + e.Message); |
||
58 | } |
||
59 | } |
||
60 | |||
61 | /// <summary> |
||
62 | /// Touches to profile time |
||
63 | /// </summary> |
||
64 | public override void TouchProfileTime() |
||
65 | { |
||
66 | base.TouchProfileTime(); |
||
67 | // save the values |
||
68 | SaveValuesToPath(GetSavePath()); |
||
69 | } |
||
70 | |||
71 | /// <summary> |
||
72 | /// Touches the check time to now, should be used after a check directly |
||
73 | /// </summary> |
||
74 | public override void TouchCheckTime() |
||
75 | { |
||
76 | base.TouchCheckTime(); |
||
77 | // save the values |
||
78 | SaveValuesToPath(GetSavePath()); |
||
79 | } |
||
80 | |||
81 | /// <summary> |
||
82 | /// This method allows to skip a specific version |
||
83 | /// </summary> |
||
84 | /// <param name="version">the version to skeip</param> |
||
85 | public override void SetVersionToSkip(string version) |
||
86 | { |
||
87 | base.SetVersionToSkip(version); |
||
88 | SaveValuesToPath(GetSavePath()); |
||
89 | } |
||
90 | |||
91 | /// <summary> |
||
92 | /// Reloads the configuration object |
||
93 | /// </summary> |
||
94 | public override void Reload() |
||
95 | { |
||
96 | LoadValuesFromPath(GetSavePath()); |
||
97 | } |
||
98 | |||
99 | /// <summary> |
||
100 | /// This function build a valid registry path in dependecy to the |
||
101 | /// assembly information |
||
102 | /// </summary> |
||
103 | public virtual string GetSavePath() |
||
104 | { |
||
105 | if (!string.IsNullOrEmpty(_savePath)) |
||
106 | { |
||
107 | return _savePath; |
||
108 | } |
||
109 | else |
||
110 | { |
||
111 | |||
112 | if (string.IsNullOrEmpty(AssemblyAccessor.AssemblyCompany) || string.IsNullOrEmpty(AssemblyAccessor.AssemblyProduct)) |
||
113 | { |
||
114 | throw new NetSparkleException("Error: NetSparkleUpdater is missing the company or productname tag in the assembly accessor (" |
||
115 | + AssemblyAccessor.GetType() + ")"); |
||
116 | } |
||
117 | var applicationFolder = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData, Environment.SpecialFolderOption.DoNotVerify); |
||
118 | var saveFolder = Path.Combine(applicationFolder, AssemblyAccessor.AssemblyCompany, AssemblyAccessor.AssemblyProduct, "NetSparkleUpdater"); |
||
119 | if (!Directory.Exists(saveFolder)) |
||
120 | { |
||
121 | Directory.CreateDirectory(saveFolder); |
||
122 | } |
||
123 | var saveLocation = Path.Combine(saveFolder, "data.json"); |
||
124 | return saveLocation; |
||
125 | } |
||
126 | } |
||
127 | |||
128 | /// <summary> |
||
129 | /// This method loads the values from registry |
||
130 | /// </summary> |
||
131 | /// <param name="saveLocation">the saved file location</param> |
||
132 | /// <returns><c>true</c> if the items were loaded</returns> |
||
133 | private bool LoadValuesFromPath(string saveLocation) |
||
134 | { |
||
135 | if (File.Exists(saveLocation)) |
||
136 | { |
||
137 | try |
||
138 | { |
||
139 | string json = File.ReadAllText(saveLocation); |
||
140 | #if NETSTANDARD |
||
141 | var data = JsonSerializer.Deserialize<SavedConfigurationData>(json); |
||
142 | #else |
||
143 | var data = JsonConvert.DeserializeObject<SavedConfigurationData>(json); |
||
144 | #endif |
||
145 | CheckForUpdate = true; |
||
146 | LastCheckTime = data.LastCheckTime; |
||
147 | LastVersionSkipped = data.LastVersionSkipped; |
||
148 | DidRunOnce = data.DidRunOnce; |
||
149 | IsFirstRun = !DidRunOnce; |
||
150 | LastConfigUpdate = data.LastConfigUpdate; |
||
151 | PreviousVersionOfSoftwareRan = data?.PreviousVersionOfSoftwareRan ?? ""; |
||
152 | if (IsFirstRun) |
||
153 | { |
||
154 | SaveDidRunOnceAsTrue(saveLocation); |
||
155 | } |
||
156 | else |
||
157 | { |
||
158 | SaveValuesToPath(saveLocation); // so PreviousVersion is set to proper value |
||
159 | } |
||
160 | return true; |
||
161 | } |
||
162 | catch (Exception) // just in case... |
||
163 | { |
||
164 | } |
||
165 | } |
||
166 | CheckForUpdate = true; |
||
167 | LastCheckTime = DateTime.Now; |
||
168 | LastVersionSkipped = string.Empty; |
||
169 | DidRunOnce = false; |
||
170 | IsFirstRun = true; |
||
171 | SaveDidRunOnceAsTrue(saveLocation); |
||
172 | LastConfigUpdate = DateTime.Now; |
||
173 | PreviousVersionOfSoftwareRan = ""; |
||
174 | return true; |
||
175 | } |
||
176 | |||
177 | private void SaveDidRunOnceAsTrue(string saveLocation) |
||
178 | { |
||
179 | var initialValue = DidRunOnce; |
||
180 | DidRunOnce = true; |
||
181 | SaveValuesToPath(saveLocation); // save it so next time we load DidRunOnce is true |
||
182 | DidRunOnce = initialValue; // so data is correct to user of Configuration class |
||
183 | } |
||
184 | |||
185 | /// <summary> |
||
186 | /// This method stores the information to disk as json |
||
187 | /// </summary> |
||
188 | /// <param name="savePath">the save path to the json file</param> |
||
189 | /// <returns><c>true</c> if the values were saved to disk</returns> |
||
190 | private bool SaveValuesToPath(string savePath) |
||
191 | { |
||
192 | var savedConfig = new SavedConfigurationData() |
||
193 | { |
||
194 | CheckForUpdate = true, |
||
195 | LastCheckTime = this.LastCheckTime, |
||
196 | LastVersionSkipped = this.LastVersionSkipped, |
||
197 | DidRunOnce = this.DidRunOnce, |
||
198 | LastConfigUpdate = DateTime.Now, |
||
199 | PreviousVersionOfSoftwareRan = InstalledVersion |
||
200 | }; |
||
201 | LastConfigUpdate = savedConfig.LastConfigUpdate; |
||
202 | |||
203 | #if NETSTANDARD |
||
204 | string json = JsonSerializer.Serialize(savedConfig); |
||
205 | #else |
||
206 | string json = JsonConvert.SerializeObject(savedConfig); |
||
207 | #endif |
||
208 | try |
||
209 | { |
||
210 | File.WriteAllText(savePath, json); |
||
211 | } |
||
212 | catch (Exception) // just in case... |
||
213 | { |
||
214 | return false; |
||
215 | } |
||
216 | |||
217 | return true; |
||
218 | } |
||
219 | } |
||
220 | } |