Prevent multiple instances, allow starting in tray, documentation edits and priority support #4
@@ -13,11 +13,13 @@ namespace ntfysh_client
 | 
				
			|||||||
    public partial class MainForm : Form
 | 
					    public partial class MainForm : Form
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        private readonly NotificationListener _notificationListener;
 | 
					        private readonly NotificationListener _notificationListener;
 | 
				
			||||||
 | 
					        private bool _startInTray;
 | 
				
			||||||
        private bool _trueExit;
 | 
					        private bool _trueExit;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        public MainForm(NotificationListener notificationListener)
 | 
					        public MainForm(NotificationListener notificationListener, bool startInTray = false)
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            _notificationListener = notificationListener;
 | 
					            _notificationListener = notificationListener;
 | 
				
			||||||
 | 
					            _startInTray = startInTray;
 | 
				
			||||||
            _notificationListener.OnNotificationReceive += OnNotificationReceive;
 | 
					            _notificationListener.OnNotificationReceive += OnNotificationReceive;
 | 
				
			||||||
            _notificationListener.OnConnectionMultiAttemptFailure += OnConnectionMultiAttemptFailure;
 | 
					            _notificationListener.OnConnectionMultiAttemptFailure += OnConnectionMultiAttemptFailure;
 | 
				
			||||||
            _notificationListener.OnConnectionCredentialsFailure += OnConnectionCredentialsFailure;
 | 
					            _notificationListener.OnConnectionCredentialsFailure += OnConnectionCredentialsFailure;
 | 
				
			||||||
@@ -25,6 +27,30 @@ namespace ntfysh_client
 | 
				
			|||||||
            InitializeComponent();
 | 
					            InitializeComponent();
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        
 | 
					        
 | 
				
			||||||
 | 
					        private void MainForm_Load(object sender, EventArgs e) => LoadTopics();
 | 
				
			||||||
 | 
					        
 | 
				
			||||||
 | 
					        protected override void SetVisibleCore(bool value)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            if (_startInTray)
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                _startInTray = false;
 | 
				
			||||||
 | 
					                
 | 
				
			||||||
 | 
					                /*
 | 
				
			||||||
 | 
					                 * TODO This little workaround prevents the window from appearing with a flash, but the taskbar icon appears for a moment.
 | 
				
			||||||
 | 
					                 *
 | 
				
			||||||
 | 
					                 * TODO This is because we must call SetVisibleCore(true) for the initial load events in the MainForm to fire, which is what triggers the listener
 | 
				
			||||||
 | 
					                 */
 | 
				
			||||||
 | 
					                Opacity = 0;
 | 
				
			||||||
 | 
					                base.SetVisibleCore(true);
 | 
				
			||||||
 | 
					                base.SetVisibleCore(false);
 | 
				
			||||||
 | 
					                Opacity = 1;
 | 
				
			||||||
 | 
					                
 | 
				
			||||||
 | 
					                return;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            
 | 
				
			||||||
 | 
					            base.SetVisibleCore(value);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        private void OnNotificationReceive(object sender, NotificationReceiveEventArgs e)
 | 
					        private void OnNotificationReceive(object sender, NotificationReceiveEventArgs e)
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            notifyIcon.ShowBalloonTip(3000, e.Title, e.Message, ToolTipIcon.Info);
 | 
					            notifyIcon.ShowBalloonTip(3000, e.Title, e.Message, ToolTipIcon.Info);
 | 
				
			||||||
@@ -42,8 +68,6 @@ namespace ntfysh_client
 | 
				
			|||||||
            MessageBox.Show($"Connecting to topic ID '{topic.TopicId}' on server '{topic.ServerUrl}' failed because {reason}.\n\nThis topic ID will be ignored and you will not receive notifications for it until you correct the credentials.", "Connection Authentication Failure", MessageBoxButtons.OK, MessageBoxIcon.Error);
 | 
					            MessageBox.Show($"Connecting to topic ID '{topic.TopicId}' on server '{topic.ServerUrl}' failed because {reason}.\n\nThis topic ID will be ignored and you will not receive notifications for it until you correct the credentials.", "Connection Authentication Failure", MessageBoxButtons.OK, MessageBoxIcon.Error);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        private void MainForm_Load(object sender, EventArgs e) => LoadTopics();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        private void subscribeNewTopic_Click(object sender, EventArgs e)
 | 
					        private void subscribeNewTopic_Click(object sender, EventArgs e)
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            using SubscribeDialog dialog = new SubscribeDialog(notificationTopics);
 | 
					            using SubscribeDialog dialog = new SubscribeDialog(notificationTopics);
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -67,7 +67,7 @@
 | 
				
			|||||||
  <data name="showControlWindowToolStripMenuItem.Image" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
 | 
					  <data name="showControlWindowToolStripMenuItem.Image" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
 | 
				
			||||||
    <value>
 | 
					    <value>
 | 
				
			||||||
        iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAALGPC/xhBQAAACBjSFJNAAB6
 | 
					        iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAALGPC/xhBQAAACBjSFJNAAB6
 | 
				
			||||||
        JgAAgIQAAPoAAACA6AAAdTAAAOpgAAA6mAAAF3CculE8AAAACXBIWXMAAA6+AAAOvgHqQrHAAAAAiklE
 | 
					        JgAAgIQAAPoAAACA6AAAdTAAAOpgAAA6mAAAF3CculE8AAAACXBIWXMAAA69AAAOvQFH+5CtAAAAiklE
 | 
				
			||||||
        QVQ4T8WPQQqAIBBFvUOrXIhu3dcZOkqtu5R1ia4SdRDrxyyGGKmBIOGBDL6nmk9WCGE9yUpW0q9Ads7V
 | 
					        QVQ4T8WPQQqAIBBFvUOrXIhu3dcZOkqtu5R1ia4SdRDrxyyGGKmBIOGBDL6nmk9WCGE9yUpW0q9Ads7V
 | 
				
			||||||
        GuCQ/kHAe79joAEO6dcLFmttpQEO6c+Bvpm2oZ0zwB4zVQBiF8cIsMdMDPCb+G2vA/wgP/z6C6WAhBgo
 | 
					        GuCQ/kHAe79joAEO6dcLFmttpQEO6c+Bvpm2oZ0zwB4zVQBiF8cIsMdMDPCb+G2vA/wgP/z6C6WAhBgo
 | 
				
			||||||
        fUFCDGi4BxIGShLpvy5jDoPes/0oNG3VAAAAAElFTkSuQmCC
 | 
					        fUFCDGi4BxIGShLpvy5jDoPes/0oNG3VAAAAAElFTkSuQmCC
 | 
				
			||||||
@@ -76,7 +76,7 @@
 | 
				
			|||||||
  <data name="exitToolStripMenuItem.Image" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
 | 
					  <data name="exitToolStripMenuItem.Image" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
 | 
				
			||||||
    <value>
 | 
					    <value>
 | 
				
			||||||
        iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAALGPC/xhBQAAACBjSFJNAAB6
 | 
					        iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAALGPC/xhBQAAACBjSFJNAAB6
 | 
				
			||||||
        JgAAgIQAAPoAAACA6AAAdTAAAOpgAAA6mAAAF3CculE8AAAACXBIWXMAAA6+AAAOvgHqQrHAAAAAgUlE
 | 
					        JgAAgIQAAPoAAACA6AAAdTAAAOpgAAA6mAAAF3CculE8AAAACXBIWXMAAA69AAAOvQFH+5CtAAAAgUlE
 | 
				
			||||||
        QVQ4T2OgGjjOLq4AZeIFWNWBBI9yib06zC3uABXCCkDyIHVYDTnMI2pzhEvs5VFucSeoEAo4wiNii08e
 | 
					        QVQ4T2OgGjjOLq4AZeIFWNWBBI9yib06zC3uABXCCkDyIHVYDTnMI2pzhEvs5VFucSeoEAo4wiNii08e
 | 
				
			||||||
        DHAZQshwFICumCTNMADyK1gTl2gJiCYUNlgBSDPQ1v8gGipEPKDIBRSFAa6oIsoQQvGM1xCqpESsglgA
 | 
					        DHAZQshwFICumCTNMADyK1gTl2gJiCYUNlgBSDPQ1v8gGipEPKDIBRSFAa6oIsoQQvGM1xCqpESsglgA
 | 
				
			||||||
        seroBRgYAOoOWBJbfVcRAAAAAElFTkSuQmCC
 | 
					        seroBRgYAOoOWBJbfVcRAAAAAElFTkSuQmCC
 | 
				
			||||||
@@ -267,7 +267,7 @@
 | 
				
			|||||||
  <data name="exitToolStripMenuItem1.Image" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
 | 
					  <data name="exitToolStripMenuItem1.Image" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
 | 
				
			||||||
    <value>
 | 
					    <value>
 | 
				
			||||||
        iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAALGPC/xhBQAAACBjSFJNAAB6
 | 
					        iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAALGPC/xhBQAAACBjSFJNAAB6
 | 
				
			||||||
        JgAAgIQAAPoAAACA6AAAdTAAAOpgAAA6mAAAF3CculE8AAAACXBIWXMAAA6+AAAOvgHqQrHAAAAAgUlE
 | 
					        JgAAgIQAAPoAAACA6AAAdTAAAOpgAAA6mAAAF3CculE8AAAACXBIWXMAAA69AAAOvQFH+5CtAAAAgUlE
 | 
				
			||||||
        QVQ4T2OgGjjOLq4AZeIFWNWBBI9yib06zC3uABXCCkDyIHVYDTnMI2pzhEvs5VFucSeoEAo4wiNii08e
 | 
					        QVQ4T2OgGjjOLq4AZeIFWNWBBI9yib06zC3uABXCCkDyIHVYDTnMI2pzhEvs5VFucSeoEAo4wiNii08e
 | 
				
			||||||
        DHAZQshwFICumCTNMADyK1gTl2gJiCYUNlgBSDPQ1v8gGipEPKDIBRSFAa6oIsoQQvGM1xCqpESsglgA
 | 
					        DHAZQshwFICumCTNMADyK1gTl2gJiCYUNlgBSDPQ1v8gGipEPKDIBRSFAa6oIsoQQvGM1xCqpESsglgA
 | 
				
			||||||
        seroBRgYAOoOWBJbfVcRAAAAAElFTkSuQmCC
 | 
					        seroBRgYAOoOWBJbfVcRAAAAAElFTkSuQmCC
 | 
				
			||||||
@@ -276,7 +276,7 @@
 | 
				
			|||||||
  <data name="ntfyshWebsiteToolStripMenuItem.Image" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
 | 
					  <data name="ntfyshWebsiteToolStripMenuItem.Image" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
 | 
				
			||||||
    <value>
 | 
					    <value>
 | 
				
			||||||
        iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAALGPC/xhBQAAACBjSFJNAAB6
 | 
					        iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAALGPC/xhBQAAACBjSFJNAAB6
 | 
				
			||||||
        JgAAgIQAAPoAAACA6AAAdTAAAOpgAAA6mAAAF3CculE8AAAACXBIWXMAAA6+AAAOvgHqQrHAAAABDElE
 | 
					        JgAAgIQAAPoAAACA6AAAdTAAAOpgAAA6mAAAF3CculE8AAAACXBIWXMAAA69AAAOvQFH+5CtAAABDElE
 | 
				
			||||||
        QVQ4T91RO3bCQAzUy3uhChdJnTVlCj5FcMsZsF1jmy4XycPrzl6fBLgEXMFp4srRiF0wcaBP5j0VI2m0
 | 
					        QVQ4T91RO3bCQAzUy3uhChdJnTVlCj5FcMsZsF1jmy4XycPrzl6fBLgEXMFp4srRiF0wcaBP5j0VI2m0
 | 
				
			||||||
        4zH9EwSq8gPP7ELPNFxtpxrbn9vVPkSsykOkqvHi2QxsWwAevhQTzG8eCb1yD7Glv2I5MlM+sLX0GqEq
 | 
					        4zH9EwSq8gPP7ELPNFxtpxrbn9vVPkSsykOkqvHi2QxsWwAevhQTzG8eCb1yD7Glv2I5MlM+sLX0GqEq
 | 
				
			||||||
        6+jVPFl6QZz7lOgdJVnzuMq/sEepbsGln2YnR3AAm0IcIE71geJsTO9mcOWAOa3zicxxxGWApXMGabaH
 | 
					        6+jVPFl6QZz7lOgdJVnzuMq/sEepbsGln2YnR3AAm0IcIE71geJsTO9mcOWAOa3zicxxxGWApXMGabaH
 | 
				
			||||||
@@ -287,7 +287,7 @@
 | 
				
			|||||||
  <data name="aboutToolStripMenuItem.Image" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
 | 
					  <data name="aboutToolStripMenuItem.Image" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
 | 
				
			||||||
    <value>
 | 
					    <value>
 | 
				
			||||||
        iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAALGPC/xhBQAAACBjSFJNAAB6
 | 
					        iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAALGPC/xhBQAAACBjSFJNAAB6
 | 
				
			||||||
        JgAAgIQAAPoAAACA6AAAdTAAAOpgAAA6mAAAF3CculE8AAAACXBIWXMAAA6+AAAOvgHqQrHAAAAAwUlE
 | 
					        JgAAgIQAAPoAAACA6AAAdTAAAOpgAAA6mAAAF3CculE8AAAACXBIWXMAAA69AAAOvQFH+5CtAAAAwUlE
 | 
				
			||||||
        QVQ4T2OgClBUVHwAxP9JxA+g2sEG/JeTk5MkBYP0QLVTwQAFBYXHIAFSMEgPVDvYBfulpKSEScEgPVDt
 | 
					        QVQ4T2OgClBUVHwAxP9JxA+g2sEG/JeTk5MkBYP0QLVTwQAFBYXHIAFSMEgPVDvYBfulpKSEScEgPVDt
 | 
				
			||||||
        dDIA6OTNQHX/YXysBjAxMcUxMjKuBrGB9DIgPxqmARhwOUBD3sD4WA0QERGRBHLvCwoKygLpm6KiohIw
 | 
					        dDIA6OTNQHX/YXysBjAxMcUxMjKuBrGB9DIgPxqmARhwOUBD3sD4WA0QERGRBHLvCwoKygLpm6KiohIw
 | 
				
			||||||
        DVBNz5HY2L0AtHkOEE8F4okgvoyMjDSSJsIGsLOzuwKFfnBycppJS0vLAJ39BUQTbQA6RnYBMkY3YAVI
 | 
					        DVBNz5HY2L0AtHkOEE8F4okgvoyMjDSSJsIGsLOzuwKFfnBycppJS0vLAJ39BUQTbQA6RnYBMkY3YAVI
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,25 +1,46 @@
 | 
				
			|||||||
using System;
 | 
					using System;
 | 
				
			||||||
using System.Collections.Generic;
 | 
					using System.Diagnostics;
 | 
				
			||||||
 | 
					using System.IO;
 | 
				
			||||||
using System.Linq;
 | 
					using System.Linq;
 | 
				
			||||||
using System.Threading.Tasks;
 | 
					using System.Reflection;
 | 
				
			||||||
using System.Windows.Forms;
 | 
					using System.Windows.Forms;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
namespace ntfysh_client
 | 
					namespace ntfysh_client
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    static class Program
 | 
					    static class Program
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        private static readonly NotificationListener NotificationListener = new NotificationListener();
 | 
					        private static readonly NotificationListener NotificationListener = new();
 | 
				
			||||||
        
 | 
					        
 | 
				
			||||||
        /// <summary>
 | 
					        /// <summary>
 | 
				
			||||||
        /// The main entry point for the application.
 | 
					        /// The main entry point for the application.
 | 
				
			||||||
        /// </summary>
 | 
					        /// </summary>
 | 
				
			||||||
        [STAThread]
 | 
					        [STAThread]
 | 
				
			||||||
        static void Main()
 | 
					        private static void Main(string[] args)
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
 | 
					            args = args.Select(a => a.ToLower()).ToArray();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            if (args.Contains("-h") || args.Contains("--help"))
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                MessageBox.Show("Help:\n    -h\n    --help\n\nStart in tray:\n    -t\n    --start-in-tray\n\nAllow multiple instances:\n    -m\n    --allow-multiple-instances", "Help Menu", MessageBoxButtons.OK, MessageBoxIcon.Information);
 | 
				
			||||||
 | 
					                return;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            bool startInTray = args.Contains("-t") || args.Contains("--start-in-tray");
 | 
				
			||||||
 | 
					            bool allowMultipleInstances = args.Contains("-m") || args.Contains("--allow-multiple-instances");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            if (Process.GetProcessesByName(Path.GetFileNameWithoutExtension(Assembly.GetEntryAssembly()!.Location)).Length > 1)
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                if (!allowMultipleInstances)
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                    MessageBox.Show("Another instance is already running.\n\nUse -m or --allow-multiple-instances if you wish to start a second duplicate instance.\n\nThis instance will now close.", "Multiple Instances", MessageBoxButtons.OK, MessageBoxIcon.Warning);
 | 
				
			||||||
 | 
					                    return;
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            
 | 
				
			||||||
            Application.SetHighDpiMode(HighDpiMode.SystemAware);
 | 
					            Application.SetHighDpiMode(HighDpiMode.SystemAware);
 | 
				
			||||||
            Application.EnableVisualStyles();
 | 
					            Application.EnableVisualStyles();
 | 
				
			||||||
            Application.SetCompatibleTextRenderingDefault(false);
 | 
					            Application.SetCompatibleTextRenderingDefault(false);
 | 
				
			||||||
            Application.Run(new MainForm(NotificationListener));
 | 
					            Application.Run(new MainForm(NotificationListener, startInTray));
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user