1
0
Эх сурвалжийг харах

Changes needed to get first stage of update checking working

Antony Male 10 жил өмнө
parent
commit
9d642d85ec

+ 2 - 2
server/version_check.php

@@ -63,7 +63,7 @@ function get_with_wildcard($src, $value, $default = null)
 }
 
 $versions = [
-   '1.0.11' => [
+   '1.0.12' => [
       'installed' => [
          'direct_download_url' => [
             'x64' => 'https://github.com/canton7/SyncTrayzor/releases/download/v1.0.11/SyncTrayzorSetup-x64.exe',
@@ -76,7 +76,7 @@ $versions = [
 ];
 
 $upgrades = [
-   '1.0.10' => ['to' => '1.0.11', 'formatter' => '1'],
+   '1.0.11' => ['to' => '1.0.12', 'formatter' => '1'],
 ];
 
 $response_formatters = [

+ 5 - 2
src/SyncTrayzor/App.config

@@ -12,8 +12,8 @@
     </startup>
     <applicationSettings>
         <SyncTrayzor.Properties.Settings>
-            <setting name="GithubApiUrl" serializeAs="String">
-                <value>https://api.github.com/repos/canton7/SyncTrayzor</value>
+            <setting name="UpdateApiUrl" serializeAs="String">
+                <value>http://localhost:8080/version-check</value>
             </setting>
             <setting name="HomepageUrl" serializeAs="String">
                 <value>http://github.com/canton7/SyncTrayzor</value>
@@ -34,6 +34,9 @@
             <setting name="CefRemoteDebuggingPort" serializeAs="String">
                 <value>0</value>
             </setting>
+            <setting name="Variant" serializeAs="String">
+                <value>installed</value>
+            </setting>
             <setting name="DefaultUserConfiguration" serializeAs="Xml">
                 <value>
                     <Configuration xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

+ 5 - 15
src/SyncTrayzor/Bootstrapper.cs

@@ -34,8 +34,10 @@ namespace SyncTrayzor
 
         protected override void ConfigureIoC(IStyletIoCBuilder builder)
         {
-            builder.Bind<IApplicationState>().ToFactory(c => new ApplicationState(this.Application, (IScreenState)this.RootViewModel)).InSingletonScope();
+            builder.Bind<IApplicationState>().ToInstance(new ApplicationState(this.Application));
+            builder.Bind<IApplicationWindowState>().ToFactory(c => new ApplicationWindowState((IScreenState)this.RootViewModel)).InSingletonScope();
             builder.Bind<IConfigurationProvider>().To<ConfigurationProvider>().InSingletonScope();
+            builder.Bind<IAssemblyProvider>().To<AssemblyProvider>().InSingletonScope();
             builder.Bind<IAutostartProvider>().To<AutostartProvider>().InSingletonScope();
             builder.Bind<ConfigurationApplicator>().ToSelf().InSingletonScope();
             builder.Bind<ISyncThingApiClientFactory>().To<SyncThingApiClientFactory>();
@@ -46,8 +48,9 @@ namespace SyncTrayzor
             builder.Bind<INotifyIconManager>().To<NotifyIconManager>().InSingletonScope();
             builder.Bind<IWatchedFolderMonitor>().To<WatchedFolderMonitor>().InSingletonScope();
             builder.Bind<IUpdateManager>().To<UpdateManager>().InSingletonScope();
-            builder.Bind<IUpdateChecker>().To<UpdateChecker>();
+            builder.Bind<IUpdateCheckerFactory>().To<UpdateCheckerFactory>();
             builder.Bind<IUpdatePromptProvider>().To<UpdatePromptProvider>();
+            builder.Bind<IUpdateNotificationClientFactory>().To<UpdateNotificationClientFactory>();
             builder.Bind<IProcessStartProvider>().To<ProcessStartProvider>().InSingletonScope();
 
             builder.Bind(typeof(IModelValidator<>)).To(typeof(FluentModelValidator<>));
@@ -96,15 +99,6 @@ namespace SyncTrayzor
             // https://github.com/cefsharp/CefSharp/issues/800#issuecomment-75058534
             this.Application.SessionEnding += (o, e) => Process.GetCurrentProcess().Kill();
 
-            if (configurationProvider.Load().NotifyOfNewVersions)
-            {
-                SystemEvents.PowerModeChanged += (o, e) =>
-                {
-                    if (e.Mode == PowerModes.Resume)
-                        this.Container.Get<IUpdateChecker>().CheckForAcceptableUpdateAsync();
-                };
-            }
-
             MessageBoxViewModel.ButtonLabels = new Dictionary<MessageBoxResult, string>()
             {
                 { MessageBoxResult.Cancel, Localizer.Translate("Generic_Dialog_Cancel") },
@@ -129,10 +123,6 @@ namespace SyncTrayzor
             var config = this.Container.Get<IConfigurationProvider>().Load();
             if (config.StartSyncthingAutomatically && !this.Args.Contains("-noautostart"))
                 ((ShellViewModel)this.RootViewModel).Start();
-
-            // We don't care if this fails
-            if (config.NotifyOfNewVersions)
-                this.Container.Get<IUpdateChecker>().CheckForAcceptableUpdateAsync();
         }
 
         protected override void OnUnhandledException(DispatcherUnhandledExceptionEventArgs e)

+ 2 - 2
src/SyncTrayzor/Pages/AboutViewModel.cs

@@ -37,12 +37,12 @@ namespace SyncTrayzor.Pages
             IWindowManager windowManager,
             ISyncThingManager syncThingManager,
             IConfigurationProvider configurationProvider,
-            IUpdateChecker updateChecker,
+            //IUpdateChecker updateChecker,
             Func<ThirdPartyComponentsViewModel> thirdPartyComponentsViewModelFactory)
         {
             this.windowManager = windowManager;
             this.syncThingManager = syncThingManager;
-            this.updateChecker = updateChecker;
+            //this.updateChecker = updateChecker;
             this.thirdPartyComponentsViewModelFactory = thirdPartyComponentsViewModelFactory;
 
             this.Version = Assembly.GetExecutingAssembly().GetName().Version.ToString(3);

+ 1 - 1
src/SyncTrayzor/Pages/NewVersionAlertView.xaml

@@ -7,7 +7,7 @@
         Title="{l:Loc NewVersionAlertView_Title}"
         SizeToContent="Height">
     <DockPanel Margin="10">
-        <TextBlock DockPanel.Dock="Top" TextWrapping="Wrap" FontWeight="Bold" FontSize="14" HorizontalAlignment="Center">>
+        <TextBlock DockPanel.Dock="Top" TextWrapping="Wrap">
             <ContentControl Content="{l:Loc NewVersionAlertView_NewVersionAvailable, ValueBinding={Binding Version}}"/>
         </TextBlock>
         <TextBlock DockPanel.Dock="Top" Margin="0,10,0,0" Text="{l:Loc NewVersionAlertView_Changelog}"/>

+ 5 - 0
src/SyncTrayzor/Pages/ShellViewModel.cs

@@ -153,6 +153,11 @@ namespace SyncTrayzor.Pages
             this.RequestClose();
         }
 
+        public void Shutdown()
+        {
+            this.application.Shutdown();
+        }
+
         public void EnsureInForeground()
         {
             if (!this.application.HasMainWindow)

+ 40 - 29
src/SyncTrayzor/Properties/Settings.Designer.cs

@@ -1,7 +1,7 @@
 //------------------------------------------------------------------------------
 // <auto-generated>
 //     This code was generated by a tool.
-//     Runtime Version:4.0.30319.0
+//     Runtime Version:4.0.30319.18444
 //
 //     Changes to this file may cause incorrect behavior and will be lost if
 //     the code is regenerated.
@@ -25,10 +25,10 @@ namespace SyncTrayzor.Properties {
         
         [global::System.Configuration.ApplicationScopedSettingAttribute()]
         [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
-        [global::System.Configuration.DefaultSettingValueAttribute("https://api.github.com/repos/canton7/SyncTrayzor")]
-        public global::System.Uri GithubApiUrl {
+        [global::System.Configuration.DefaultSettingValueAttribute("http://localhost:8080/version-check")]
+        public string UpdateApiUrl {
             get {
-                return ((global::System.Uri)(this["GithubApiUrl"]));
+                return ((string)(this["UpdateApiUrl"]));
             }
         }
         
@@ -88,24 +88,34 @@ namespace SyncTrayzor.Properties {
         
         [global::System.Configuration.ApplicationScopedSettingAttribute()]
         [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
-        [global::System.Configuration.DefaultSettingValueAttribute(@"<?xml version=""1.0"" encoding=""utf-16""?>
-<Configuration xmlns:xsi=""http://www.w3.org/2001/XMLSchema-instance"" xmlns:xsd=""http://www.w3.org/2001/XMLSchema"">
-  <ShowTrayIconOnlyOnClose>false</ShowTrayIconOnlyOnClose>
-  <MinimizeToTray>false</MinimizeToTray>
-  <CloseToTray>true</CloseToTray>
-  <ShowSynchronizedBalloon>true</ShowSynchronizedBalloon>
-  <ShowDeviceConnectivityBalloons>true</ShowDeviceConnectivityBalloons>
-  <SyncthingAddress>localhost:8384</SyncthingAddress>
-  <StartSyncthingAutomatically>true</StartSyncthingAutomatically>
-  <SyncthingUseCustomHome>true</SyncthingUseCustomHome>
-  <SyncthingDenyUpgrade>false</SyncthingDenyUpgrade>
-  <SyncthingRunLowPriority>false</SyncthingRunLowPriority>
-  <Folders />
-  <NotifyOfNewVersions>true</NotifyOfNewVersions>
-  <ObfuscateDeviceIDs>true</ObfuscateDeviceIDs>
-  <UseComputerCulture>true</UseComputerCulture>
-  <ShowSyncthingConsole>true</ShowSyncthingConsole>
-</Configuration>")]
+        [global::System.Configuration.DefaultSettingValueAttribute("installed")]
+        public string Variant {
+            get {
+                return ((string)(this["Variant"]));
+            }
+        }
+        
+        [global::System.Configuration.ApplicationScopedSettingAttribute()]
+        [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+        [global::System.Configuration.DefaultSettingValueAttribute(@"
+                    <Configuration xmlns:xsi=""http://www.w3.org/2001/XMLSchema-instance"" xmlns:xsd=""http://www.w3.org/2001/XMLSchema"">
+                        <ShowTrayIconOnlyOnClose>false</ShowTrayIconOnlyOnClose>
+                        <MinimizeToTray>false</MinimizeToTray>
+                        <CloseToTray>true</CloseToTray>
+                        <ShowSynchronizedBalloon>true</ShowSynchronizedBalloon>
+                        <ShowDeviceConnectivityBalloons>true</ShowDeviceConnectivityBalloons>
+                        <SyncthingAddress>localhost:8384</SyncthingAddress>
+                        <StartSyncthingAutomatically>true</StartSyncthingAutomatically>
+                        <SyncthingUseCustomHome>true</SyncthingUseCustomHome>
+                        <SyncthingDenyUpgrade>false</SyncthingDenyUpgrade>
+                        <SyncthingRunLowPriority>false</SyncthingRunLowPriority>
+                        <Folders />
+                        <NotifyOfNewVersions>true</NotifyOfNewVersions>
+                        <ObfuscateDeviceIDs>true</ObfuscateDeviceIDs>
+                        <UseComputerCulture>true</UseComputerCulture>
+                        <ShowSyncthingConsole>true</ShowSyncthingConsole>
+                    </Configuration>
+                ")]
         public global::SyncTrayzor.Services.Config.Configuration DefaultUserConfiguration {
             get {
                 return ((global::SyncTrayzor.Services.Config.Configuration)(this["DefaultUserConfiguration"]));
@@ -114,13 +124,14 @@ namespace SyncTrayzor.Properties {
         
         [global::System.Configuration.ApplicationScopedSettingAttribute()]
         [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
-        [global::System.Configuration.DefaultSettingValueAttribute(@"<?xml version=""1.0"" encoding=""utf-16""?>
-<PathConfiguration xmlns:xsi=""http://www.w3.org/2001/XMLSchema-instance"" xmlns:xsd=""http://www.w3.org/2001/XMLSchema"">
-  <LogFilePath>%EXEPATH%\data\logs</LogFilePath>
-  <SyncthingCustomHomePath>%EXEPATH%\data\syncthing</SyncthingCustomHomePath>
-  <SyncthingPath>%EXEPATH%\syncthing.exe</SyncthingPath>
-  <ConfigurationFilePath>%EXEPATH%\data\config.xml</ConfigurationFilePath>
-</PathConfiguration>")]
+        [global::System.Configuration.DefaultSettingValueAttribute(@"
+                    <PathConfiguration xmlns:xsi=""http://www.w3.org/2001/XMLSchema-instance"" xmlns:xsd=""http://www.w3.org/2001/XMLSchema"">
+                        <LogFilePath>%EXEPATH%\data\logs</LogFilePath>
+                        <SyncthingCustomHomePath>%EXEPATH%\data\syncthing</SyncthingCustomHomePath>
+                        <SyncthingPath>%EXEPATH%\syncthing.exe</SyncthingPath>
+                        <ConfigurationFilePath>%EXEPATH%\data\config.xml</ConfigurationFilePath>
+                    </PathConfiguration>
+                ")]
         public global::SyncTrayzor.Services.Config.PathConfiguration PathConfiguration {
             get {
                 return ((global::SyncTrayzor.Services.Config.PathConfiguration)(this["PathConfiguration"]));

+ 32 - 27
src/SyncTrayzor/Properties/Settings.settings

@@ -2,8 +2,8 @@
 <SettingsFile xmlns="http://schemas.microsoft.com/VisualStudio/2004/01/settings" CurrentProfile="(Default)" GeneratedClassNamespace="SyncTrayzor.Properties" GeneratedClassName="Settings">
   <Profiles />
   <Settings>
-    <Setting Name="GithubApiUrl" Type="System.Uri" Scope="Application">
-      <Value Profile="(Default)">https://api.github.com/repos/canton7/SyncTrayzor</Value>
+    <Setting Name="UpdateApiUrl" Type="System.String" Scope="Application">
+      <Value Profile="(Default)">http://localhost:8080/version-check</Value>
     </Setting>
     <Setting Name="HomepageUrl" Type="System.String" Scope="Application">
       <Value Profile="(Default)">http://github.com/canton7/SyncTrayzor</Value>
@@ -23,34 +23,39 @@
     <Setting Name="CefRemoteDebuggingPort" Type="System.Int32" Scope="Application">
       <Value Profile="(Default)">0</Value>
     </Setting>
+    <Setting Name="Variant" Type="System.String" Scope="Application">
+      <Value Profile="(Default)">installed</Value>
+    </Setting>
     <Setting Name="DefaultUserConfiguration" Type="SyncTrayzor.Services.Config.Configuration" Scope="Application">
-      <Value Profile="(Default)">&lt;?xml version="1.0" encoding="utf-16"?&gt;
-&lt;Configuration xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"&gt;
-  &lt;ShowTrayIconOnlyOnClose&gt;false&lt;/ShowTrayIconOnlyOnClose&gt;
-  &lt;MinimizeToTray&gt;false&lt;/MinimizeToTray&gt;
-  &lt;CloseToTray&gt;true&lt;/CloseToTray&gt;
-  &lt;ShowSynchronizedBalloon&gt;true&lt;/ShowSynchronizedBalloon&gt;
-  &lt;ShowDeviceConnectivityBalloons&gt;true&lt;/ShowDeviceConnectivityBalloons&gt;
-  &lt;SyncthingAddress&gt;localhost:8384&lt;/SyncthingAddress&gt;
-  &lt;StartSyncthingAutomatically&gt;true&lt;/StartSyncthingAutomatically&gt;
-  &lt;SyncthingUseCustomHome&gt;true&lt;/SyncthingUseCustomHome&gt;
-  &lt;SyncthingDenyUpgrade&gt;false&lt;/SyncthingDenyUpgrade&gt;
-  &lt;SyncthingRunLowPriority&gt;false&lt;/SyncthingRunLowPriority&gt;
-  &lt;Folders /&gt;
-  &lt;NotifyOfNewVersions&gt;true&lt;/NotifyOfNewVersions&gt;
-  &lt;ObfuscateDeviceIDs&gt;true&lt;/ObfuscateDeviceIDs&gt;
-  &lt;UseComputerCulture&gt;true&lt;/UseComputerCulture&gt;
-  &lt;ShowSyncthingConsole&gt;true&lt;/ShowSyncthingConsole&gt;
-&lt;/Configuration&gt;</Value>
+      <Value Profile="(Default)">
+                    &lt;Configuration xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"&gt;
+                        &lt;ShowTrayIconOnlyOnClose&gt;false&lt;/ShowTrayIconOnlyOnClose&gt;
+                        &lt;MinimizeToTray&gt;false&lt;/MinimizeToTray&gt;
+                        &lt;CloseToTray&gt;true&lt;/CloseToTray&gt;
+                        &lt;ShowSynchronizedBalloon&gt;true&lt;/ShowSynchronizedBalloon&gt;
+                        &lt;ShowDeviceConnectivityBalloons&gt;true&lt;/ShowDeviceConnectivityBalloons&gt;
+                        &lt;SyncthingAddress&gt;localhost:8384&lt;/SyncthingAddress&gt;
+                        &lt;StartSyncthingAutomatically&gt;true&lt;/StartSyncthingAutomatically&gt;
+                        &lt;SyncthingUseCustomHome&gt;true&lt;/SyncthingUseCustomHome&gt;
+                        &lt;SyncthingDenyUpgrade&gt;false&lt;/SyncthingDenyUpgrade&gt;
+                        &lt;SyncthingRunLowPriority&gt;false&lt;/SyncthingRunLowPriority&gt;
+                        &lt;Folders /&gt;
+                        &lt;NotifyOfNewVersions&gt;true&lt;/NotifyOfNewVersions&gt;
+                        &lt;ObfuscateDeviceIDs&gt;true&lt;/ObfuscateDeviceIDs&gt;
+                        &lt;UseComputerCulture&gt;true&lt;/UseComputerCulture&gt;
+                        &lt;ShowSyncthingConsole&gt;true&lt;/ShowSyncthingConsole&gt;
+                    &lt;/Configuration&gt;
+                </Value>
     </Setting>
     <Setting Name="PathConfiguration" Type="SyncTrayzor.Services.Config.PathConfiguration" Scope="Application">
-      <Value Profile="(Default)">&lt;?xml version="1.0" encoding="utf-16"?&gt;
-&lt;PathConfiguration xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"&gt;
-  &lt;LogFilePath&gt;%EXEPATH%\data\logs&lt;/LogFilePath&gt;
-  &lt;SyncthingCustomHomePath&gt;%EXEPATH%\data\syncthing&lt;/SyncthingCustomHomePath&gt;
-  &lt;SyncthingPath&gt;%EXEPATH%\syncthing.exe&lt;/SyncthingPath&gt;
-  &lt;ConfigurationFilePath&gt;%EXEPATH%\data\config.xml&lt;/ConfigurationFilePath&gt;
-&lt;/PathConfiguration&gt;</Value>
+      <Value Profile="(Default)">
+                    &lt;PathConfiguration xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"&gt;
+                        &lt;LogFilePath&gt;%EXEPATH%\data\logs&lt;/LogFilePath&gt;
+                        &lt;SyncthingCustomHomePath&gt;%EXEPATH%\data\syncthing&lt;/SyncthingCustomHomePath&gt;
+                        &lt;SyncthingPath&gt;%EXEPATH%\syncthing.exe&lt;/SyncthingPath&gt;
+                        &lt;ConfigurationFilePath&gt;%EXEPATH%\data\config.xml&lt;/ConfigurationFilePath&gt;
+                    &lt;/PathConfiguration&gt;
+                </Value>
     </Setting>
   </Settings>
 </SettingsFile>

+ 1 - 24
src/SyncTrayzor/Services/ApplicationState.cs

@@ -11,9 +11,6 @@ namespace SyncTrayzor.Services
 {
     public interface IApplicationState
     {
-        event EventHandler<ActivationEventArgs> RootWindowActivated;
-        event EventHandler<DeactivationEventArgs> RootWindowDeactivated;
-        event EventHandler<CloseEventArgs> RootWindowClosed;
         event EventHandler Startup;
         event EventHandler ResumeFromSleep;
 
@@ -27,33 +24,13 @@ namespace SyncTrayzor.Services
     public class ApplicationState : IApplicationState
     {
         private readonly Application application;
-        private readonly IScreenState rootViewModel;
-
-        public event EventHandler<ActivationEventArgs> RootWindowActivated
-        {
-            add { this.rootViewModel.Activated += value; }
-            remove { this.rootViewModel.Activated -= value; }
-        }
-
-        public event EventHandler<DeactivationEventArgs> RootWindowDeactivated
-        {
-            add { this.rootViewModel.Deactivated += value; }
-            remove { this.rootViewModel.Deactivated -= value; }
-        }
-
-        public event EventHandler<CloseEventArgs> RootWindowClosed
-        {
-            add { this.rootViewModel.Closed += value; }
-            remove { this.rootViewModel.Closed -= value; }
-        }
 
         public event EventHandler Startup;
         public event EventHandler ResumeFromSleep;
 
-        public ApplicationState(Application application, IScreenState rootViewModel)
+        public ApplicationState(Application application)
         {
             this.application = application;
-            this.rootViewModel = rootViewModel;
 
             SystemEvents.PowerModeChanged += (o, e) =>
             {

+ 44 - 0
src/SyncTrayzor/Services/ApplicationWindowState.cs

@@ -0,0 +1,44 @@
+using Stylet;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace SyncTrayzor.Services
+{
+    public interface IApplicationWindowState
+    {
+        event EventHandler<ActivationEventArgs> RootWindowActivated;
+        event EventHandler<DeactivationEventArgs> RootWindowDeactivated;
+        event EventHandler<CloseEventArgs> RootWindowClosed;
+    }
+
+    public class ApplicationWindowState : IApplicationWindowState
+    {
+        private readonly IScreenState rootViewModel;
+
+        public ApplicationWindowState(IScreenState rootViewModel)
+        {
+            this.rootViewModel = rootViewModel;
+        }
+
+        public event EventHandler<ActivationEventArgs> RootWindowActivated
+        {
+            add { this.rootViewModel.Activated += value; }
+            remove { this.rootViewModel.Activated -= value; }
+        }
+
+        public event EventHandler<DeactivationEventArgs> RootWindowDeactivated
+        {
+            add { this.rootViewModel.Deactivated += value; }
+            remove { this.rootViewModel.Deactivated -= value; }
+        }
+
+        public event EventHandler<CloseEventArgs> RootWindowClosed
+        {
+            add { this.rootViewModel.Closed += value; }
+            remove { this.rootViewModel.Closed -= value; }
+        }
+    }
+}

+ 4 - 0
src/SyncTrayzor/Services/ConfigurationApplicator.cs

@@ -48,6 +48,10 @@ namespace SyncTrayzor.Services
             this.watchedFolderMonitor.FolderExistenceCheckingInterval = TimeSpan.FromMilliseconds(Settings.Default.DirectoryWatcherFolderExistenceCheckMilliseconds);
 
             this.syncThingManager.ExecutablePath = this.configurationProvider.SyncthingPath;
+
+            this.updateManager.UpdateCheckApiUrl = Settings.Default.UpdateApiUrl;
+            this.updateManager.Variant = Settings.Default.Variant;
+
             this.ApplyNewConfiguration(this.configurationProvider.Load());
         }
 

+ 3 - 3
src/SyncTrayzor/Services/UpdateManagement/UpdateChecker.cs

@@ -28,13 +28,13 @@ namespace SyncTrayzor.Services.UpdateManagement
             this.NewVersion = newVersion;
             this.DownloadUrl = downloadUrl;
             this.ReleaseNotes = releaseNotes;
-            this.ReleasePageUrl = ReleasePageUrl;
+            this.ReleasePageUrl = releasePageUrl;
         }
 
         public override string ToString()
         {
             return String.Format("<VersionCheckResults NewVersion={0} DownloadUrl={1} ReleaseNotes={2} ReleasePageUrl={3}>",
-                this.NewVersion, this.DownloadUrl, this.ReleasePageUrl);
+                this.NewVersion, this.DownloadUrl, this.ReleaseNotes, this.ReleasePageUrl);
         }
     }
 
@@ -54,7 +54,7 @@ namespace SyncTrayzor.Services.UpdateManagement
             { ProcessorArchitecture.IA64, "x64" },
             { ProcessorArchitecture.MSIL, "msil" },
             { ProcessorArchitecture.None, "none" },
-            { ProcessorArchitecture.X86, "86" }
+            { ProcessorArchitecture.X86, "x86" }
         };
 
         private readonly Version applicationVersion;

+ 60 - 38
src/SyncTrayzor/Services/UpdateManagement/UpdateManager.cs

@@ -39,11 +39,14 @@ namespace SyncTrayzor.Services.UpdateManagement
         private static readonly TimeSpan timeBetweenChecks = TimeSpan.FromHours(3);
 
         private readonly IApplicationState applicationState;
+        private readonly IApplicationWindowState applicationWindowState;
         private readonly IUpdateCheckerFactory updateCheckerFactory;
         private readonly IProcessStartProvider processStartProvider;
         private readonly IUpdatePromptProvider updatePromptProvider;
         private readonly System.Timers.Timer promptTimer;
 
+        private readonly SemaphoreSlim versionCheckLock = new SemaphoreSlim(1, 1);
+
         private DateTime lastCheckedTime;
 
         public event EventHandler<VersionIgnoredEventArgs> VersionIgnored;
@@ -66,11 +69,13 @@ namespace SyncTrayzor.Services.UpdateManagement
 
         public UpdateManager(
             IApplicationState applicationState,
+            IApplicationWindowState applicationWindowState,
             IUpdateCheckerFactory updateCheckerFactory,
             IProcessStartProvider processStartProvider,
             IUpdatePromptProvider updatePromptProvider)
         {
             this.applicationState = applicationState;
+            this.applicationWindowState = applicationWindowState;
             this.updateCheckerFactory = updateCheckerFactory;
             this.processStartProvider = processStartProvider;
             this.updatePromptProvider = updatePromptProvider;
@@ -84,7 +89,7 @@ namespace SyncTrayzor.Services.UpdateManagement
             // We'll also check when the application is restored from tray
 
             this.applicationState.Startup += this.ApplicationStartup;
-            this.applicationState.RootWindowActivated += this.RootWindowActivated;
+            this.applicationWindowState.RootWindowActivated += this.RootWindowActivated;
         }
 
         private async void UpdateCheckForUpdates(bool checkForUpdates)
@@ -93,7 +98,11 @@ namespace SyncTrayzor.Services.UpdateManagement
             {
                 this.RestartTimer();
                 if (this.UpdateCheckDue())
+                {
+                    // Give them a minute to catch their breath
+                    await Task.Delay(TimeSpan.FromSeconds(30));
                     await this.CheckForUpdatesAsync();
+                }
             }
             else
             {
@@ -139,53 +148,66 @@ namespace SyncTrayzor.Services.UpdateManagement
 
         private async Task CheckForUpdatesAsync()
         {
-            this.lastCheckedTime = DateTime.UtcNow;
-
-            if (!this.CheckForUpdates)
+            if (!this.versionCheckLock.Wait(0))
                 return;
 
-            this.RestartTimer();
+            try
+            {
+                this.lastCheckedTime = DateTime.UtcNow;
 
-            var updateChecker = this.updateCheckerFactory.CreateUpdateChecker(this.UpdateCheckApiUrl, this.Variant);
-            var checkResult = await updateChecker.CheckForAcceptableUpdateAsync(this.LatestIgnoredVersion);
+                if (!this.CheckForUpdates)
+                    return;
 
-            VersionPromptResult promptResult;
-            if (this.applicationState.HasMainWindow)
-            {
-                promptResult = this.updatePromptProvider.ShowDialog(checkResult);
-            }
-            else
-            {
-                try
+                this.RestartTimer();
+
+                var updateChecker = this.updateCheckerFactory.CreateUpdateChecker(this.UpdateCheckApiUrl, this.Variant);
+                var checkResult = await updateChecker.CheckForAcceptableUpdateAsync(this.LatestIgnoredVersion);
+
+                if (checkResult == null)
+                    return;
+
+                VersionPromptResult promptResult;
+                if (this.applicationState.HasMainWindow)
                 {
-                    promptResult = await this.updatePromptProvider.ShowToast(checkResult, CancellationToken.None);
+                    promptResult = this.updatePromptProvider.ShowDialog(checkResult);
                 }
-                catch (OperationCanceledException)
+                else
                 {
-                    logger.Info("Update toast cancelled");
-                    return;
+                    try
+                    {
+                        promptResult = await this.updatePromptProvider.ShowToast(checkResult, CancellationToken.None);
+                    }
+                    catch (OperationCanceledException)
+                    {
+                        logger.Info("Update toast cancelled");
+                        return;
+                    }
                 }
-            }
 
-            switch (promptResult)
+                switch (promptResult)
+                {
+                    case VersionPromptResult.Download:
+                        logger.Info("Proceeding to download URL {0}", checkResult.DownloadUrl);
+                        this.processStartProvider.Start(checkResult.DownloadUrl);
+                        break;
+
+                    case VersionPromptResult.Ignore:
+                        logger.Info("Ignoring version {0}", checkResult.NewVersion);
+                        this.OnVersionIgnored(checkResult.NewVersion);
+                        break;
+
+                    case VersionPromptResult.RemindLater:
+                        logger.Info("Not installing version {0}, but will remind later", checkResult.NewVersion);
+                        break;
+
+                    default:
+                        Debug.Assert(false);
+                        break;
+                }
+            }
+            finally
             {
-                case VersionPromptResult.Download:
-                    logger.Info("Proceeding to download URL {0}", checkResult.DownloadUrl);
-                    this.processStartProvider.Start(checkResult.DownloadUrl);
-                    break;
-
-                case VersionPromptResult.Ignore:
-                    logger.Info("Ignoring version {0}", checkResult.NewVersion);
-                    this.OnVersionIgnored(checkResult.NewVersion);
-                    break;
-
-                case VersionPromptResult.RemindLater:
-                    logger.Info("Not installing version {0}, but will remind later", checkResult.NewVersion);
-                    break;
-
-                default:
-                    Debug.Assert(false);
-                    break;
+                this.versionCheckLock.Release();
             }
         }
     }

+ 1 - 0
src/SyncTrayzor/SyncTrayzor.csproj

@@ -120,6 +120,7 @@
       <DependentUpon>App.xaml</DependentUpon>
       <SubType>Code</SubType>
     </Compile>
+    <Compile Include="Services\ApplicationWindowState.cs" />
     <Compile Include="Services\AssemblyProvider.cs" />
     <Compile Include="Services\ProcessStartProvider.cs" />
     <Compile Include="Services\UpdateManagement\IUpdateNotificationApi.cs" />