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();