diff --git a/DesktopEdge/Assets/Images/processing.png b/DesktopEdge/Assets/Images/processing.png
new file mode 100644
index 00000000..e7fcfe4f
Binary files /dev/null and b/DesktopEdge/Assets/Images/processing.png differ
diff --git a/DesktopEdge/MainWindow.xaml.cs b/DesktopEdge/MainWindow.xaml.cs
index a95372fb..8e04e49d 100644
--- a/DesktopEdge/MainWindow.xaml.cs
+++ b/DesktopEdge/MainWindow.xaml.cs
@@ -648,7 +648,9 @@ namespace ZitiDesktopEdge {
}
private void MonitorClient_OnCommunicationError(object sender, Exception e) {
- ShowError("Communication Error", e.Message);
+ string msg = "Communication Error with monitor?";
+ logger.Warn(msg);
+ ShowError(msg, e.Message);
}
private void MainMenu_OnShowBlurb(string message) {
@@ -755,7 +757,8 @@ namespace ZitiDesktopEdge {
string nextVersionStr = null;
private void MonitorClient_OnReconnectFailure(object sender, object e) {
- if (nextVersionStr == null) {
+ logger.Debug("OnReconnectFailure triggered");
+ if (nextVersionStr == null) {
// check for the current version
nextVersionStr = "checking for update";
Version nextVersion = VersionUtil.NormalizeVersion(GithubAPI.GetVersion(GithubAPI.GetJson(GithubAPI.ProdUrl)));
@@ -779,6 +782,7 @@ namespace ZitiDesktopEdge {
private void MonitorClient_OnShutdownEvent(object sender, StatusEvent e)
{
+ logger.Info("The monitor has indicated the application should shut down.");
this.Dispatcher.Invoke(() => {
Application.Current.Shutdown();
});
@@ -795,6 +799,7 @@ namespace ZitiDesktopEdge {
}
logger.Debug("MonitorClient_OnServiceStatusEvent: {0}", evt.Status);
Application.Current.Properties["ReleaseStream"] = evt.ReleaseStream;
+ Application.Current.Properties["AutomaticUpgradeDisabled"] = evt.AutomaticUpgradeDisabled;
ServiceControllerStatus status = (ServiceControllerStatus)Enum.Parse(typeof(ServiceControllerStatus), evt.Status);
switch (status) {
diff --git a/DesktopEdge/Views/Screens/MainMenu.xaml b/DesktopEdge/Views/Screens/MainMenu.xaml
index 8f424d0a..bc90f7b6 100644
--- a/DesktopEdge/Views/Screens/MainMenu.xaml
+++ b/DesktopEdge/Views/Screens/MainMenu.xaml
@@ -64,6 +64,7 @@
+
@@ -96,6 +97,10 @@
+
+
+
+
diff --git a/DesktopEdge/Views/Screens/MainMenu.xaml.cs b/DesktopEdge/Views/Screens/MainMenu.xaml.cs
index df6383be..aaaef3a9 100644
--- a/DesktopEdge/Views/Screens/MainMenu.xaml.cs
+++ b/DesktopEdge/Views/Screens/MainMenu.xaml.cs
@@ -35,12 +35,18 @@ namespace ZitiDesktopEdge {
private string appVersion = null;
private bool allowReleaseSelect = false;
public double MainHeight = 500;
-
+
private bool isBeta {
get {
return Application.Current.Properties["ReleaseStream"]?.ToString() == "beta";
}
}
+ private bool automaticUpgradeDisabled {
+ get
+ {
+ return bool.TrueString.ToLower() == ("" + Application.Current.Properties["AutomaticUpgradeDisabled"]?.ToString()).ToLower().Trim();
+ }
+ }
public void ShowUpdateAvailable(double timeLeft, DateTime updateTime) {
ForceUpdate.Visibility = Visibility.Visible;
@@ -124,6 +130,12 @@ namespace ZitiDesktopEdge {
UpdateState();
}
+ private void ShowAutomaticUpgradesMenuAction(object sender, MouseButtonEventArgs e)
+ {
+ menuState = "ConfigureAutomaticUpgrades";
+ UpdateState();
+ }
+
async private void SetReleaseStreamMenuAction(object sender, MouseButtonEventArgs e) {
CheckForUpdateStatus.Visibility = Visibility.Collapsed;
TriggerUpdateButton.Visibility = Visibility.Collapsed;
@@ -154,6 +166,22 @@ namespace ZitiDesktopEdge {
UpdateState();
}
+ async private void SetAutomaticUpgradesMenuAction(object sender, MouseButtonEventArgs e) {
+ bool disableAutomaticUpgrades = false;
+ if (sender == AutomaticUpgradesItemOff) {
+ disableAutomaticUpgrades = true;
+ }
+ var monitorClient = (MonitorClient)Application.Current.Properties["MonitorClient"];
+
+ SvcResponse r = await monitorClient.SetAutomaticUpgradeDisabledAsync(disableAutomaticUpgrades);
+ if(r.Code != 0) {
+ logger.Error(r?.Error);
+ } else {
+ Application.Current.Properties["AutomaticUpgradeDisabled"] = disableAutomaticUpgrades;
+ }
+ SetAutomaticUpgradesState(disableAutomaticUpgrades);
+ }
+
private void checkResponse(SvcResponse r, string titleOnErr, string msgOnErr) {
if (r == null) {
MainWindow.ShowError(titleOnErr, msgOnErr);
@@ -168,7 +196,10 @@ namespace ZitiDesktopEdge {
}
private void UpdateState() {
- IdListScrollView.Height = this.ActualHeight-100.00;
+ double h = this.ActualHeight - 100.00;
+ if (h > 0) {
+ IdListScrollView.Height = h;
+ }
IdListScrollView.Visibility = Visibility.Collapsed;
MainItems.Visibility = Visibility.Collapsed;
AboutItems.Visibility = Visibility.Collapsed;
@@ -181,7 +212,8 @@ namespace ZitiDesktopEdge {
ConfigItems.Visibility = Visibility.Collapsed;
LogLevelItems.Visibility = Visibility.Collapsed;
ReleaseStreamItems.Visibility = Visibility.Collapsed;
-
+ AutomaticUpgradesItems.Visibility = Visibility.Collapsed;
+
if (menuState == "About") {
MenuTitle.Content = "About";
AboutItemsArea.Visibility = Visibility.Visible;
@@ -233,12 +265,18 @@ namespace ZitiDesktopEdge {
MenuTitle.Content = "Set Release Stream";
ReleaseStreamItems.Visibility = allowReleaseSelect ? Visibility.Visible : Visibility.Collapsed;
BackArrow.Visibility = Visibility.Visible;
+ } else if (menuState == "ConfigureAutomaticUpgrades") {
+ SetAutomaticUpgradesState(automaticUpgradeDisabled);
+
+ MenuTitle.Content = "Automatic Upgrades";
+ AutomaticUpgradesItems.Visibility = Visibility.Visible;
+ BackArrow.Visibility = Visibility.Visible;
} else if (menuState == "Config") {
MenuTitle.Content = "Tunnel Configuration";
ConfigItems.Visibility = Visibility.Visible;
BackArrow.Visibility = Visibility.Visible;
- ConfigPageSize.Value = ((Application.Current.Properties.Contains("ApiPageSize"))?Application.Current.Properties["ApiPageSize"].ToString(): "250");
+ ConfigPageSize.Value = ((Application.Current.Properties.Contains("ApiPageSize"))?Application.Current.Properties["ApiPageSize"].ToString(): "25");
ConfigIp.Value = Application.Current.Properties["ip"]?.ToString();
ConfigSubnet.Value = Application.Current.Properties["subnet"]?.ToString();
ConfigMtu.Value = Application.Current.Properties["mtu"]?.ToString();
@@ -278,7 +316,7 @@ namespace ZitiDesktopEdge {
}
private void GoBack(object sender, MouseButtonEventArgs e) {
- if (menuState == "Config" || menuState == "LogLevel" || menuState == "UILogs" || menuState == "SetReleaseStream") {
+ if (menuState == "Config" || menuState == "LogLevel" || menuState == "UILogs" || menuState == "SetReleaseStream" || menuState == "ConfigureAutomaticUpgrades") {
menuState = "Advanced";
} else if (menuState == "Licenses") {
menuState = "About";
@@ -391,6 +429,10 @@ namespace ZitiDesktopEdge {
this.ReleaseStreamItemBeta.IsSelected = isBeta;
this.ReleaseStreamItemStable.IsSelected = !isBeta;
}
+ private void SetAutomaticUpgradesState(bool yesNo) {
+ this.AutomaticUpgradesItemOn.IsSelected = !yesNo;
+ this.AutomaticUpgradesItemOff.IsSelected = yesNo;
+ }
async private void CheckForUpdate_Click(object sender, RoutedEventArgs e) {
logger.Info("checking for update...");
diff --git a/DesktopEdge/ZitiDesktopEdge.csproj b/DesktopEdge/ZitiDesktopEdge.csproj
index e7116423..abdb6a8c 100644
--- a/DesktopEdge/ZitiDesktopEdge.csproj
+++ b/DesktopEdge/ZitiDesktopEdge.csproj
@@ -473,5 +473,8 @@
+
+
+
\ No newline at end of file
diff --git a/ZitiDesktopEdge.Client/DataStructures/DataStructures.cs b/ZitiDesktopEdge.Client/DataStructures/DataStructures.cs
index f12a61f6..bc9b44b9 100644
--- a/ZitiDesktopEdge.Client/DataStructures/DataStructures.cs
+++ b/ZitiDesktopEdge.Client/DataStructures/DataStructures.cs
@@ -478,9 +478,16 @@ namespace ZitiDesktopEdge.DataStructures {
}
+ public class MonitorConfigEvent : ActionEvent
+ {
+ public bool AutomaticUpdatesDisabled { get; set; }
+ }
+
+
public class MonitorServiceStatusEvent : SvcResponse {
public string Status { get; set; }
public string ReleaseStream { get; set; }
+ public string AutomaticUpgradeDisabled { get; set; }
public bool IsStopped() {
return "Stopped" == this.Status;
diff --git a/ZitiDesktopEdge.Client/Server/IPCServer.cs b/ZitiDesktopEdge.Client/Server/IPCServer.cs
index b3b39133..3c6442b4 100644
--- a/ZitiDesktopEdge.Client/Server/IPCServer.cs
+++ b/ZitiDesktopEdge.Client/Server/IPCServer.cs
@@ -39,6 +39,9 @@ namespace ZitiDesktopEdge.Server {
public delegate SvcResponse TriggerUpdateDelegate();
public TriggerUpdateDelegate TriggerUpdate { get; set; }
+ public delegate SvcResponse SetAutomaticUpdateDisabledDelegate(bool disabled);
+ public SetAutomaticUpdateDisabledDelegate SetAutomaticUpdateDisabled { get; set; }
+
public IPCServer() {
ipcPipeName = PipeName;
eventPipeName = EventPipeName;
@@ -234,6 +237,9 @@ namespace ZitiDesktopEdge.Server {
case "triggerupdate":
r = TriggerUpdate();
break;
+ case "setautomaticupgradedisabled":
+ r = SetAutomaticUpdateDisabled(bool.TrueString.ToLower() == ("" + ae.Action).ToLower().Trim());
+ break;
default:
r.Message = "FAILURE";
r.Code = -3;
diff --git a/ZitiDesktopEdge.Client/ServiceClient/DataClient.cs b/ZitiDesktopEdge.Client/ServiceClient/DataClient.cs
index 79f58ba8..b8b76a4a 100644
--- a/ZitiDesktopEdge.Client/ServiceClient/DataClient.cs
+++ b/ZitiDesktopEdge.Client/ServiceClient/DataClient.cs
@@ -4,14 +4,12 @@ using System.IO;
using System.IO.Pipes;
using System.Security.Principal;
using System.Security.AccessControl;
-using System.Threading;
using System.Threading.Tasks;
using Newtonsoft.Json;
using NLog;
using ZitiDesktopEdge.DataStructures;
-using ZitiDesktopEdge.Server;
///
/// The implementation will abstract away the setup of the communication to
@@ -413,7 +411,7 @@ namespace ZitiDesktopEdge.ServiceClient {
//almost certainly a problem with the pipe - recreate the pipe...
//setupPipe();
//throw ioe;
- Logger.Error(ioe, "Unexpected error");
+ Logger.Error(ioe, "Could not perform ziti dump. Unexpected error. Is ziti running?");
}
return;
}
diff --git a/ZitiDesktopEdge.Client/ServiceClient/MonitorClient.cs b/ZitiDesktopEdge.Client/ServiceClient/MonitorClient.cs
index 51a650ca..7e5ff171 100644
--- a/ZitiDesktopEdge.Client/ServiceClient/MonitorClient.cs
+++ b/ZitiDesktopEdge.Client/ServiceClient/MonitorClient.cs
@@ -67,6 +67,10 @@ namespace ZitiDesktopEdge.ServiceClient {
var instEvt = serializer.Deserialize(new JsonTextReader(new StringReader(line)));
InstallationNotificationEvent(instEvt);
break;
+ case "Config":
+ var cfg = serializer.Deserialize(new JsonTextReader(new StringReader(line)));
+ Logger.Debug("CONFIG EVENT: " + cfg.AutomaticUpdatesDisabled);
+ break;
default:
ServiceStatusEvent(evt);
break;
@@ -135,6 +139,7 @@ namespace ZitiDesktopEdge.ServiceClient {
}
return null;
}
+
async public Task SetReleaseStreamAsync(string stream) {
ActionEvent action = new ActionEvent() { Op = "SetReleaseStream", Action = stream };
try {
@@ -179,5 +184,15 @@ namespace ZitiDesktopEdge.ServiceClient {
}
return null;
}
+ async public Task SetAutomaticUpgradeDisabledAsync(bool disabled) {
+ ActionEvent action = new ActionEvent() { Op = "SetAutomaticUpgradeDisabled", Action = (disabled ? "true" : "false")};
+ try {
+ await sendAsync(action);
+ return await readAsync(ipcReader);
+ } catch (Exception ex) {
+ Logger.Error(ex, "Unexpected error");
+ }
+ return null;
+ }
}
}
\ No newline at end of file
diff --git a/ZitiUpdateService/Properties/app.manifest b/ZitiUpdateService/Properties/app.manifest
index 3b5ed3da..60eec770 100644
--- a/ZitiUpdateService/Properties/app.manifest
+++ b/ZitiUpdateService/Properties/app.manifest
@@ -19,8 +19,8 @@
-
+
diff --git a/ZitiUpdateService/UpdateService.cs b/ZitiUpdateService/UpdateService.cs
index 6c6cab57..9cf00a84 100644
--- a/ZitiUpdateService/UpdateService.cs
+++ b/ZitiUpdateService/UpdateService.cs
@@ -21,12 +21,13 @@ using Newtonsoft.Json;
using System.Net;
using DnsClient;
using DnsClient.Protocol;
-using ZitiUpdateService.Checkers.PeFile;
+using ZitiUpdateService.Utils;
using ZitiUpdateService.Checkers;
namespace ZitiUpdateService {
public partial class UpdateService : ServiceBase {
private string betaStreamMarkerFile = "use-beta-stream.txt";
+ private static Settings CurrentSettings = new Settings(true);
public bool IsBeta {
get {
@@ -34,6 +35,12 @@ namespace ZitiUpdateService {
}
private set { }
}
+ public bool AutomaticUpgradeDisabled {
+ get {
+ return CurrentSettings.AutomaticUpdatesDisabled;
+ }
+ private set { }
+ }
private static readonly Logger Logger = LogManager.GetCurrentClassLogger();
@@ -62,6 +69,10 @@ namespace ZitiUpdateService {
public UpdateService() {
InitializeComponent();
+
+ CurrentSettings.Load();
+ CurrentSettings.OnConfigurationChange += CurrentSettings_OnConfigurationChange;
+
base.CanHandlePowerEvent = true;
exeLocation = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
@@ -79,6 +90,7 @@ namespace ZitiUpdateService {
svr.SetReleaseStream = SetReleaseStream;
svr.DoUpdateCheck = DoUpdateCheck;
svr.TriggerUpdate = TriggerUpdate;
+ svr.SetAutomaticUpdateDisabled = SetAutomaticUpdateDisabled;
string assemblyVersionStr = Assembly.GetExecutingAssembly().GetName().Version.ToString(); //fetch from ziti?
assemblyVersion = new Version(assemblyVersionStr);
@@ -90,7 +102,28 @@ namespace ZitiUpdateService {
}
}
- private SvcResponse TriggerUpdate() {
+ private void CurrentSettings_OnConfigurationChange(object sender, ControllerEvent e)
+ {
+ MonitorServiceStatusEvent status = new MonitorServiceStatusEvent() {
+ Code = 0,
+ Error = "",
+ Message = "Configuration Changed",
+ Status = ServiceActions.ServiceStatus(),
+ ReleaseStream = IsBeta ? "beta" : "stable",
+ AutomaticUpgradeDisabled = AutomaticUpgradeDisabled.ToString()
+ };
+ EventRegistry.SendEventToConsumers(status);
+ }
+
+ private SvcResponse SetAutomaticUpdateDisabled(bool disabled) {
+ CurrentSettings.AutomaticUpdatesDisabled = disabled;
+ CurrentSettings.Write();
+ SvcResponse r = new SvcResponse();
+ r.Message = "Success";
+ return r;
+ }
+
+ private SvcResponse TriggerUpdate() {
SvcResponse r = new SvcResponse();
r.Message = "Initiating Update";
@@ -136,7 +169,7 @@ namespace ZitiUpdateService {
private void SetLogLevel(string level) {
try {
Logger.Info("request to change log level received: {0}", level);
- if (("" + level).ToLower() == "verbose")
+ if (("" + level).ToLower().Trim() == "verbose")
{
level = "trace";
Logger.Info("request to change log level to verbose - but using trace instead");
@@ -445,7 +478,7 @@ namespace ZitiUpdateService {
int dnsProbeIntervalInSeconds = 60;
bool dnsProbeStarted = false;
- private void DnsProbe_Elapsed(object sender, ElapsedEventArgs e) {
+ private void DnsProbe_Elapsed(object sender, ElapsedEventArgs e) {
if (dnsProbeStarted) return; //skip out if it's already going...
dnsProbeStarted = true;
Logger.Trace("dns probe started");
@@ -501,7 +534,7 @@ namespace ZitiUpdateService {
}
}
- async private Task onEventsClientAsync(StreamWriter writer) {
+ async private Task onEventsClientAsync(StreamWriter writer) {
Logger.Info("a new events client was connected");
//reset to release stream
//initial status when connecting the event stream
@@ -511,7 +544,8 @@ namespace ZitiUpdateService {
Message = "Success",
Type = "Status",
Status = ServiceActions.ServiceStatus(),
- ReleaseStream = IsBeta ? "beta" : "stable"
+ ReleaseStream = IsBeta ? "beta" : "stable",
+ AutomaticUpgradeDisabled = AutomaticUpgradeDisabled.ToString()
};
await writer.WriteLineAsync(JsonConvert.SerializeObject(status));
await writer.FlushAsync();
@@ -584,8 +618,8 @@ namespace ZitiUpdateService {
upInt = new TimeSpan(0, 10, 0);
}
- if (upInt.TotalMilliseconds < 10 * 60 * 60 * 1000)
- {
+ if (upInt.TotalMilliseconds < 10 * 60 * 1000)
+ {
Logger.Warn("provided time [{0}] is too small. Using 10 minutes.", updateTimerInterval);
#if MOCKUPDATE || ALLOWFASTINTERVAL
Logger.Info("MOCKUPDATE detected. Not limiting check to 10 minutes");
@@ -636,7 +670,7 @@ namespace ZitiUpdateService {
static DateTime mockDate = DateTime.Now;
#endif
private UpdateCheck getCheck(Version v)
- {
+ {
#if MOCKUPDATE
//run with MOCKUPDATE to enable debugging/mocking the update check
var check = new FilesystemCheck(v, -1, mockDate, "FilesysteCheck.download.mock.txt", new Version("2.1.4"));
@@ -724,15 +758,15 @@ namespace ZitiUpdateService {
#if !SKIPUPDATE
new SignedFileValidator(fileDestination).Verify();
try {
- StopZiti();
- StopUI().Wait();
+ StopZiti();
+ StopUI().Wait();
- Logger.Info("Running update package: " + fileDestination);
- // shell out to a new process and run the uninstall, reinstall steps which SHOULD stop this current process as well
- Process.Start(fileDestination, "/passive");
- } catch (Exception ex) {
- Logger.Error(ex, "Unexpected error during installation");
- }
+ Logger.Info("Running update package: " + fileDestination);
+ // shell out to a new process and run the uninstall, reinstall steps which SHOULD stop this current process as well
+ Process.Start(fileDestination, "/passive");
+ } catch (Exception ex) {
+ Logger.Error(ex, "Unexpected error during installation");
+ }
#else
Logger.Warn("SKIPUPDATE IS SET - NOT PERFORMING UPDATE");
Logger.Warn("SKIPUPDATE IS SET - NOT PERFORMING UPDATE");
@@ -910,7 +944,8 @@ namespace ZitiUpdateService {
Code = 0,
Error = "SERVICE DOWN",
Message = "SERVICE DOWN",
- Status = ServiceActions.ServiceStatus()
+ Status = ServiceActions.ServiceStatus(),
+ AutomaticUpgradeDisabled = AutomaticUpgradeDisabled.ToString()
};
EventRegistry.SendEventToConsumers(status);
} else {
@@ -921,7 +956,8 @@ namespace ZitiUpdateService {
Error = "SERVICE DOWN",
Message = "SERVICE DOWN",
Status = ServiceActions.ServiceStatus(),
- ReleaseStream = IsBeta ? "beta" : "stable"
+ ReleaseStream = IsBeta ? "beta" : "stable",
+ AutomaticUpgradeDisabled = AutomaticUpgradeDisabled.ToString()
};
EventRegistry.SendEventToConsumers(status);
}
@@ -966,7 +1002,7 @@ namespace ZitiUpdateService {
}
private bool InstallationIsCritical(DateTime publishDate)
- {
+ {
var installationReminderIntervalStr = ConfigurationManager.AppSettings.Get("InstallationCritical");
var instCritTimespan = TimeSpan.Zero;
if (!TimeSpan.TryParse(installationReminderIntervalStr, out instCritTimespan))
diff --git a/ZitiUpdateService/ZitiUpdateService.csproj b/ZitiUpdateService/ZitiUpdateService.csproj
index e8828d5b..5af66053 100644
--- a/ZitiUpdateService/ZitiUpdateService.csproj
+++ b/ZitiUpdateService/ZitiUpdateService.csproj
@@ -61,7 +61,7 @@
- true
+ false
LocalIntranet
@@ -160,6 +160,7 @@
ProjectInstaller.cs
+
Component
diff --git a/ZitiUpdateService/checkers/GithubCheck.cs b/ZitiUpdateService/checkers/GithubCheck.cs
index 7e213c46..fa456f44 100644
--- a/ZitiUpdateService/checkers/GithubCheck.cs
+++ b/ZitiUpdateService/checkers/GithubCheck.cs
@@ -97,6 +97,7 @@ namespace ZitiUpdateService.Checkers {
string computed = BitConverter.ToString(sha256bytes).Replace("-", "");
File.Delete(sha256dest);
+ Logger.Info("comparing computed hash: {0} to downloaded hash: {1}", computed, hash);
return computed.ToLower().Trim() == hash.ToLower().Trim();
}
}
diff --git a/ZitiUpdateService/utils/Settings.cs b/ZitiUpdateService/utils/Settings.cs
new file mode 100644
index 00000000..1d95f209
--- /dev/null
+++ b/ZitiUpdateService/utils/Settings.cs
@@ -0,0 +1,119 @@
+using System.IO;
+using Newtonsoft.Json;
+using NLog;
+using ZitiDesktopEdge.DataStructures;
+
+namespace ZitiUpdateService.Utils
+{
+ internal class Settings
+ {
+ private static readonly Logger Logger = LogManager.GetCurrentClassLogger();
+ private FileSystemWatcher watcher;
+
+ [JsonIgnore]
+ private string Location { get; set; }
+
+ public bool AutomaticUpdatesDisabled { get; set; }
+
+ public event System.EventHandler OnConfigurationChange;
+
+ internal Settings(bool doInit)
+ {
+ if (doInit)
+ {
+ init();
+ }
+ }
+
+ public Settings()
+ {
+ }
+
+ private void init()
+ {
+ string folder = Path.Combine(System.Environment.GetFolderPath(System.Environment.SpecialFolder.ApplicationData), "NetFoundry", "ZitiUpdateService");
+ string file = "settings.json";
+ Location = Path.Combine(folder, file);
+ Directory.CreateDirectory(folder);
+ watcher = new FileSystemWatcher(folder);
+ watcher.Filter = file;
+
+ watcher.NotifyFilter = NotifyFilters.Attributes
+ | NotifyFilters.CreationTime
+ | NotifyFilters.DirectoryName
+ | NotifyFilters.FileName
+ | NotifyFilters.LastAccess
+ | NotifyFilters.LastWrite
+ | NotifyFilters.Security
+ | NotifyFilters.Size;
+ watcher.Changed += OnChanged;
+ watcher.Deleted += OnDeleted;
+ watcher.Renamed += OnRenamed;
+ watcher.Error += OnError;
+ watcher.EnableRaisingEvents = true;
+ }
+
+ private static JsonSerializer serializer = new JsonSerializer() { Formatting = Formatting.Indented };
+ internal void Load()
+ {
+ try
+ {
+ string json = File.ReadAllText(Location);
+ var jsonReaderEvt = new JsonTextReader(new StringReader(json));
+ Settings s = serializer.Deserialize(jsonReaderEvt);
+ Update(s);
+ }
+ catch
+ {
+ // do nothing
+ }
+ }
+ internal void Write()
+ {
+ try
+ {
+ using (StreamWriter file = File.CreateText(Location))
+ {
+ serializer.Serialize(file, this);
+ }
+ this.OnConfigurationChange?.Invoke(null, null);
+ }
+ catch
+ {
+ // do nothing
+ }
+ }
+
+
+ private static void OnError(object sender, ErrorEventArgs e)
+ {
+ }
+
+ private void OnRenamed(object sender, RenamedEventArgs e)
+ {
+ Logger.Info("Settings file renamed. Resetting to defaults...");
+ this.Update(new Settings());
+ }
+
+ private void OnDeleted(object sender, FileSystemEventArgs e)
+ {
+ Logger.Info("Settings file deleted. Resetting to defaults...");
+ this.Update(new Settings());
+ }
+
+ private void OnCreated(object sender, FileSystemEventArgs e)
+ {
+ }
+
+ private void OnChanged(object sender, FileSystemEventArgs e)
+ {
+ Logger.Info("Settings file changed. Reloading...");
+ this.Load();
+ }
+
+ private void Update(Settings source)
+ {
+ this.AutomaticUpdatesDisabled = source.AutomaticUpdatesDisabled;
+ }
+ }
+}