From 8f4e3444491b07c9695f21c8fb09fccae861c1c3 Mon Sep 17 00:00:00 2001 From: Danil Kislov Date: Fri, 22 Mar 2019 16:16:57 +0300 Subject: [PATCH] =?UTF-8?q?=D0=92=D0=BE=D1=81=D1=81=D1=82=D0=B0=D0=BD?= =?UTF-8?q?=D0=B0=D0=B2=D0=BB=D0=B8=D0=B2=D0=B0=D0=B5=D0=BC=D1=81=D1=8F=20?= =?UTF-8?q?=D0=BF=D1=80=D0=B8=20=D0=BF=D0=BE=D0=B2=D1=82=D0=BE=D1=80=D0=BD?= =?UTF-8?q?=D0=BE=D0=BC=20=D0=B7=D0=B0=D0=BF=D1=83=D1=81=D0=BA=D0=B5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .semver.txt | 2 +- src/JiraTimeBot/JiraTimeBot.csproj | 1 + src/JiraTimeBot/Program.cs | 3 +- src/JiraTimeBot/Properties/AssemblyInfo.cs | 62 +++++++++++----------- src/JiraTimeBot/UI/Tray/SingleInstance.cs | 35 ++++++++++++ src/JiraTimeBot/UI/frmMain.cs | 10 ++++ 6 files changed, 80 insertions(+), 33 deletions(-) create mode 100644 src/JiraTimeBot/UI/Tray/SingleInstance.cs diff --git a/.semver.txt b/.semver.txt index 15245f3..e8eb7f1 100644 --- a/.semver.txt +++ b/.semver.txt @@ -1 +1 @@ -1.0.32 +1.0.33 diff --git a/src/JiraTimeBot/JiraTimeBot.csproj b/src/JiraTimeBot/JiraTimeBot.csproj index ca04000..f8efc9e 100644 --- a/src/JiraTimeBot/JiraTimeBot.csproj +++ b/src/JiraTimeBot/JiraTimeBot.csproj @@ -116,6 +116,7 @@ frmSettings.cs + diff --git a/src/JiraTimeBot/Program.cs b/src/JiraTimeBot/Program.cs index e126dac..f333ff1 100644 --- a/src/JiraTimeBot/Program.cs +++ b/src/JiraTimeBot/Program.cs @@ -4,6 +4,7 @@ using System.Diagnostics; using System.Runtime.InteropServices; using System.Threading; using System.Windows.Forms; +using JiraTimeBot.UI.Tray; namespace JiraTimeBot { @@ -25,7 +26,7 @@ namespace JiraTimeBot } else { - MessageBox.Show("Another instance of the app is already running."); + SingleInstance.ShowFirstInstance(); } } } diff --git a/src/JiraTimeBot/Properties/AssemblyInfo.cs b/src/JiraTimeBot/Properties/AssemblyInfo.cs index 0feb50c..896fe5a 100644 --- a/src/JiraTimeBot/Properties/AssemblyInfo.cs +++ b/src/JiraTimeBot/Properties/AssemblyInfo.cs @@ -1,31 +1,31 @@ -using System.Reflection; -using System.Runtime.InteropServices; -// 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("JiraTimeBot")] -[assembly: AssemblyDescription("")] -[assembly: AssemblyConfiguration("")] -[assembly: AssemblyCompany("")] -[assembly: AssemblyProduct("JiraTimeBot")] -[assembly: AssemblyCopyright("Copyright © 2019")] -[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)] -// The following GUID is for the ID of the typelib if this project is exposed to COM -[assembly: Guid("f3b89316-c38c-4ce6-9d88-0b1373cfba1a")] -// 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.32")] -[assembly: AssemblyFileVersion("1.0.32")] -[assembly: AssemblyInformationalVersion("1.0.32")] +using System.Reflection; +using System.Runtime.InteropServices; +// 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("JiraTimeBot")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("")] +[assembly: AssemblyProduct("JiraTimeBot")] +[assembly: AssemblyCopyright("Copyright © 2019")] +[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)] +// The following GUID is for the ID of the typelib if this project is exposed to COM +[assembly: Guid("f3b89316-c38c-4ce6-9d88-0b1373cfba1a")] +// 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.33")] +[assembly: AssemblyFileVersion("1.0.33")] +[assembly: AssemblyInformationalVersion("1.0.33")] diff --git a/src/JiraTimeBot/UI/Tray/SingleInstance.cs b/src/JiraTimeBot/UI/Tray/SingleInstance.cs new file mode 100644 index 0000000..8a4f6f3 --- /dev/null +++ b/src/JiraTimeBot/UI/Tray/SingleInstance.cs @@ -0,0 +1,35 @@ +using System; +using System.Reflection; +using System.Runtime.InteropServices; + +namespace JiraTimeBot.UI.Tray +{ + static class SingleInstance + { + public static readonly int WM_SHOWFIRSTINSTANCE = RegisterWindowMessage($"WM_SHOWFIRSTINSTANCE|{AssemblyGuid}"); + + public static void ShowFirstInstance() + { + const int HWND_BROADCAST = 0xffff; + PostMessage((IntPtr)HWND_BROADCAST, WM_SHOWFIRSTINSTANCE, IntPtr.Zero, IntPtr.Zero); + } + + public static string AssemblyGuid + { + get + { + object[] attributes = Assembly.GetEntryAssembly().GetCustomAttributes(typeof(System.Runtime.InteropServices.GuidAttribute), false); + if (attributes.Length == 0) { + return string.Empty; + } + return ((GuidAttribute)attributes[0]).Value; + } + } + + [DllImport("user32")] + public static extern int RegisterWindowMessage(string message); + + [DllImport("user32")] + public static extern bool PostMessage(IntPtr hwnd, int msg, IntPtr wparam, IntPtr lparam); + } +} diff --git a/src/JiraTimeBot/UI/frmMain.cs b/src/JiraTimeBot/UI/frmMain.cs index 973edad..8a67f27 100644 --- a/src/JiraTimeBot/UI/frmMain.cs +++ b/src/JiraTimeBot/UI/frmMain.cs @@ -31,6 +31,16 @@ namespace JiraTimeBot.UI private readonly Action _settingsErrorReporter; private bool _updateChecked; + protected override void WndProc(ref Message message) + { + if (message.Msg == SingleInstance.WM_SHOWFIRSTINSTANCE) { + this.Show(); + this.WindowState = FormWindowState.Normal; + _trayIcon.Hide(); + } + base.WndProc(ref message); + } + private CancellationTokenSource GetTokenSource() { var tokenSource = new CancellationTokenSource();