diff --git a/App.xaml.cs b/App.xaml.cs index 70f5078..77cc29a 100644 --- a/App.xaml.cs +++ b/App.xaml.cs @@ -1,10 +1,11 @@ -using System; -using System.Windows; - -using Common.Helpers; +using Common.Helpers; using Common.IO; using Common.Wpf.Extensions; - +using Squirrel; +using System; +using System.Threading.Tasks; +using System.Windows; +using System.Windows.Threading; using Settings = WorkIndicator.Properties.Settings; namespace WorkIndicator @@ -13,29 +14,69 @@ namespace WorkIndicator { private IDisposable _isolationHandle; + public static string UpdateUrl = "https://github.com/ckaczor/WorkIndicator"; + + private Dispatcher _dispatcher; + + [STAThread] + public static void Main(string[] args) + { + SquirrelAwareApp.HandleEvents(onAppUpdate: version => Common.Settings.Extensions.RestoreSettings()); + + var application = new App(); + application.InitializeComponent(); + application.Run(); + } + protected override void OnStartup(StartupEventArgs e) { base.OnStartup(e); - // Create an isolation handle to see if we are already running - _isolationHandle = ApplicationIsolation.GetIsolationHandle(); - - // If there is another copy then pass it the command line and exit - if (_isolationHandle == null) - { - InterprocessMessageSender.SendMessage(Environment.CommandLine); - Shutdown(); - return; - } - - // Set automatic start into the registry - Current.SetStartWithWindows(Settings.Default.StartWithWindows); + _dispatcher = Dispatcher.CurrentDispatcher; // Initialize the tray icon TrayIcon.Initialize(); - // Initialize the light controller - LightController.Initialize(); + Task.Factory.StartNew(UpdateApp).ContinueWith(task => StartUpdate(task.Result.Result)); + } + + private void StartUpdate(bool updateRequired) + { + if (updateRequired) + return; + + Task.Factory.StartNew(() => + { + // Create an isolation handle to see if we are already running + _isolationHandle = ApplicationIsolation.GetIsolationHandle(); + + // If there is another copy then pass it the command line and exit + if (_isolationHandle == null) + { + InterprocessMessageSender.SendMessage(Environment.CommandLine); + Shutdown(); + return; + } + + // Set automatic start into the registry + Current.SetStartWithWindows(Settings.Default.StartWithWindows); + + // Initialize the light controller + LightController.Initialize(); + }); + } + + private async Task UpdateApp() + { + return await UpdateCheck.CheckUpdate(HandleUpdateStatus); + } + + private void HandleUpdateStatus(UpdateCheck.UpdateStatus status, string message) + { + if (status == UpdateCheck.UpdateStatus.None) + message = WorkIndicator.Properties.Resources.Loading; + + _dispatcher.Invoke(() => TrayIcon.SetText(message)); } protected override void OnExit(ExitEventArgs e) diff --git a/Common b/Common index 81ef8f4..6f528f7 160000 --- a/Common +++ b/Common @@ -1 +1 @@ -Subproject commit 81ef8f451c5ceada2ed704ecaaa789e623a7352d +Subproject commit 6f528f7b59fb4299406e8a963343e0319e2c472d diff --git a/Properties/AssemblyInfo.cs b/Properties/AssemblyInfo.cs index ee48b1b..16dbe6f 100644 --- a/Properties/AssemblyInfo.cs +++ b/Properties/AssemblyInfo.cs @@ -1,55 +1,21 @@ using System.Reflection; -using System.Resources; -using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Windows; -// General Information about an assembly is controlled through the following -// set of attributes. Change these attribute values to modify the information -// associated with an assembly. [assembly: AssemblyTitle("WorkIndicator")] [assembly: AssemblyDescription("")] [assembly: AssemblyConfiguration("")] -[assembly: AssemblyCompany("")] +[assembly: AssemblyCompany("Chris Kaczor")] [assembly: AssemblyProduct("WorkIndicator")] -[assembly: AssemblyCopyright("Copyright © 2012")] +[assembly: AssemblyCopyright("Copyright © Chris Kaczor 2012")] [assembly: AssemblyTrademark("")] [assembly: AssemblyCulture("")] -// Setting ComVisible to false makes the types in this assembly not visible -// to COM components. If you need to access a type in this assembly from -// COM, set the ComVisible attribute to true on that type. [assembly: ComVisible(false)] -//In order to begin building localizable applications, set -//CultureYouAreCodingWith in your .csproj file -//inside a . For example, if you are using US english -//in your source files, set the to en-US. Then uncomment -//the NeutralResourceLanguage attribute below. Update the "en-US" in -//the line below to match the UICulture setting in the project file. +[assembly: ThemeInfo(ResourceDictionaryLocation.None, ResourceDictionaryLocation.SourceAssembly)] -//[assembly: NeutralResourcesLanguage("en-US", UltimateResourceFallbackLocation.Satellite)] - - -[assembly: ThemeInfo( - ResourceDictionaryLocation.None, //where theme specific resource dictionaries are located - //(used if a resource is not found in the page, - // or application resource dictionaries) - ResourceDictionaryLocation.SourceAssembly //where the generic resource dictionary is located - //(used if a resource is not found in the page, - // app, or any theme specific resource dictionaries) -)] - - -// Version information for an assembly consists of the following four values: -// -// Major Version -// Minor Version -// Build Number -// Revision -// -// You can specify all the values or you can default the Build and Revision Numbers -// by using the '*' as shown below: -// [assembly: AssemblyVersion("1.0.*")] [assembly: AssemblyVersion("1.0.0.0")] [assembly: AssemblyFileVersion("1.0.0.0")] + +[assembly: AssemblyMetadata("SquirrelAwareVersion", "1")] \ No newline at end of file diff --git a/Properties/Resources.Designer.cs b/Properties/Resources.Designer.cs index 08208cd..ebca6de 100644 --- a/Properties/Resources.Designer.cs +++ b/Properties/Resources.Designer.cs @@ -19,7 +19,7 @@ namespace WorkIndicator.Properties { // class via a tool like ResGen or Visual Studio. // To add or remove a member, edit your .ResX file then rerun ResGen // with the /str option, or rebuild your VS project. - [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "15.0.0.0")] + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "17.0.0.0")] [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] public class Resources { @@ -124,6 +124,15 @@ namespace WorkIndicator.Properties { } } + /// + /// Looks up a localized string similar to Checking for update.... + /// + public static string CheckingForUpdate { + get { + return ResourceManager.GetString("CheckingForUpdate", resourceCulture); + } + } + /// /// Looks up a localized string similar to Enabled. /// @@ -169,6 +178,15 @@ namespace WorkIndicator.Properties { } } + /// + /// Looks up a localized string similar to Downloading update.... + /// + public static string DownloadingUpdate { + get { + return ResourceManager.GetString("DownloadingUpdate", resourceCulture); + } + } + /// /// Looks up a localized string similar to Edit. /// @@ -196,6 +214,33 @@ namespace WorkIndicator.Properties { } } + /// + /// Looks up a localized string similar to Installing update.... + /// + public static string InstallingUpdate { + get { + return ResourceManager.GetString("InstallingUpdate", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Loading.... + /// + public static string Loading { + get { + return ResourceManager.GetString("Loading", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to No update found. + /// + public static string NoUpdate { + get { + return ResourceManager.GetString("NoUpdate", resourceCulture); + } + } + /// /// Looks up a localized string similar to OK. /// @@ -278,6 +323,15 @@ namespace WorkIndicator.Properties { } } + /// + /// Looks up a localized string similar to Restarting application.... + /// + public static string RestartingAfterUpdate { + get { + return ResourceManager.GetString("RestartingAfterUpdate", resourceCulture); + } + } + /// /// Looks up a localized string similar to _Start when Windows starts. /// @@ -314,6 +368,15 @@ namespace WorkIndicator.Properties { } } + /// + /// Looks up a localized string similar to Updating application.... + /// + public static string Updating { + get { + return ResourceManager.GetString("Updating", resourceCulture); + } + } + /// /// Looks up a localized string similar to _Enabled:. /// diff --git a/Properties/Resources.resx b/Properties/Resources.resx index 9bea373..ec7c0fd 100644 --- a/Properties/Resources.resx +++ b/Properties/Resources.resx @@ -220,4 +220,25 @@ Working + + Checking for update... + + + Downloading update... + + + No update found + + + Updating application... + + + Restarting application... + + + Installing update... + + + Loading... + \ No newline at end of file diff --git a/TrayIcon.cs b/TrayIcon.cs index 4b4b217..84138fc 100644 --- a/TrayIcon.cs +++ b/TrayIcon.cs @@ -68,6 +68,11 @@ namespace WorkIndicator _initialized = true; } + public static void SetText(string text) + { + _trayIcon.Text = text; + } + static void HandleContextMenuStripOpening(object sender, System.ComponentModel.CancelEventArgs e) { foreach (ToolStripItem menuItem in _trayIcon.ContextMenuStrip.Items) diff --git a/UpdateCheck.cs b/UpdateCheck.cs new file mode 100644 index 0000000..2dface6 --- /dev/null +++ b/UpdateCheck.cs @@ -0,0 +1,71 @@ +using Squirrel; +using System; +using System.Linq; +using System.Net; +using System.Reflection; +using System.Threading.Tasks; + +namespace WorkIndicator +{ + public static class UpdateCheck + { + public enum UpdateStatus + { + Checking, + None, + Downloading, + Installing, + Restarting + } + + public delegate void UpdateStatusDelegate(UpdateStatus updateStatus, string message); + + public static Version LocalVersion => Assembly.GetEntryAssembly().GetName().Version; + + public static async Task CheckUpdate(UpdateStatusDelegate onUpdateStatus) + { + try + { + onUpdateStatus.Invoke(UpdateStatus.Checking, Properties.Resources.CheckingForUpdate); + + ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12; + + using (var updateManager = await UpdateManager.GitHubUpdateManager(App.UpdateUrl)) + { + var updates = await updateManager.CheckForUpdate(); + + var lastVersion = updates?.ReleasesToApply?.OrderBy(releaseEntry => releaseEntry.Version).LastOrDefault(); + + if (lastVersion == null) + { + onUpdateStatus.Invoke(UpdateStatus.None, Properties.Resources.NoUpdate); + return false; + } + + onUpdateStatus.Invoke(UpdateStatus.Downloading, Properties.Resources.DownloadingUpdate); + + Common.Settings.Extensions.BackupSettings(); + + await updateManager.DownloadReleases(new[] { lastVersion }); + + onUpdateStatus.Invoke(UpdateStatus.Installing, Properties.Resources.InstallingUpdate); + + await updateManager.ApplyReleases(updates); + await updateManager.UpdateApp(); + } + + onUpdateStatus.Invoke(UpdateStatus.Restarting, Properties.Resources.RestartingAfterUpdate); + + UpdateManager.RestartApp(); + + return true; + } + catch (Exception exception) + { + Console.WriteLine(exception); + + return false; + } + } + } +} diff --git a/WorkIndicator.csproj b/WorkIndicator.csproj index ee84f82..908b693 100644 --- a/WorkIndicator.csproj +++ b/WorkIndicator.csproj @@ -143,10 +143,11 @@ - + + MSBuild:Compile Designer - + @@ -188,6 +189,7 @@ Designer + SettingsSingleFileGenerator @@ -234,6 +236,9 @@ 13.0.1 + + 2.0.1 + diff --git a/appveyor.yml b/appveyor.yml new file mode 100644 index 0000000..9a94455 --- /dev/null +++ b/appveyor.yml @@ -0,0 +1,31 @@ +version: 1.0.{build} +pull_requests: + do_not_increment_build_number: true +skip_tags: true +image: Visual Studio 2017 +configuration: Release +assembly_info: + patch: true + file: 'Properties\AssemblyInfo.cs' + assembly_version: '{version}' + assembly_file_version: '{version}' +build: + project: WorkIndicator.sln + verbosity: minimal +after_build: +- ps: >- + nuget pack WorkIndicator.nuspec -Version $env:APPVEYOR_BUILD_VERSION -Properties Configuration=Release -OutputDirectory bin\Release\ + + $squirrel = ".\packages\squirrel.windows.*\tools\Squirrel.exe" + + .$squirrel -releasify ".\bin\$env:CONFIGURATION\WorkIndicator.$env:APPVEYOR_BUILD_VERSION.nupkg" | Write-Output +artifacts: +- path: Releases\* + name: Releases +deploy: +- provider: Environment + name: GitHub +install: +- cmd: git submodule update --init --recursive +before_build: +- cmd: nuget restore \ No newline at end of file