May 29, 2016

In this article I will explain you how to make windows application as singleton in c#. We can use Remoting or Mutex to make application as singleton. We can also use Microsoft.VisualBasic assembly  to make application as singleton. I do not want to have dependency on Microsoft.Visual basic.  I will go with mutex approach.
Mutex is used for interprocess synchronization. There are many locking constructs in .Net like Monitor and Lock. But they only work with in process. Here we need synchronization between multiple processes so we cannot use Monitor or lock. We have to use Mutex or Semaphore. Here is the code to implement singleton logic.


using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Runtime.InteropServices;
using System.Threading;
using System.Windows.Forms;

namespace SingleApplication
{
    static class Program
    {
        static Mutext cmutex = null;
        internal static readonly int WM_SHOWFIRSTINSTANCE = WinFunctions.RegisterWindowMessage("WM_SHOWFIRSTINSTANCE|{0}", "Out Custom Message");
   
        static void Main() 
        {
            cmutex = new Mutex(false, string.Format("Global\\" + GetUniqueId);  // Create global mutex, If Mutex names starts with Global then systemwide mutex is created
            bool lockAccuired;

            try
            {
                try
                {
                    lockAccuired = cmutex.WaitOne(1000);
                }
                catch(AbandonedMutexException)
                {
                    //abandoned exeption is thrown when that thread that owned the mutex does not release it. If any thread tries to accuire 
                    //abandoned mutex then this exception is thrown. However now calling thread has accuried mutex.
                    lockAccuired = true;
                } 
                catch
                {
                    lockAccuired = false;
                }

                if(lockAccuired)
                {
                    Application.EnableVisualStyles();
                    Application.SetCompatibleTextRenderingDefault(false);
                    Application.Run(new Form1());
                }
                else
                {
                    WinFunctions.PostMessage((IntPtr)WinFunctions.HWND_BROADCAST,WM_SHOWFIRSTINSTANCE,IntPtr.Zero,IntPtr.Zero);
                }
            }
            finally
            {
                if(lockAccuired)
                {
                    cmutex.ReleaseMutex();
                }
            }

            //signals garbage collector to not garbage collect this object while the application is running.
            GC.KeepAlive(cmutex);
        }

        string GetUniqueId
        {
            get
            {
                var attributes = Assembly.GetEntryAssembly().GetCustomAttributes(typeof(GuidAttribute), false);
                if(attributes.Length == 0)
                    return string.Empty;
                return ((GuidAttribute)attributes[0])).Value;
            }
        }
    }

    static public class WinFunctions
    {
        public const int HWND_BROADCAST = 0xffff;
        public const int SW_SHOWNORMAL = 1;
        
        //This native function is used to register message.
        [DllImport("user32")]
        public static extern int RegisterWindowMessage(string message);

        public static int RegisterWindowMessage(string format, params object[] args)
        {
            string message = String.Format(format, args);
            return RegisterWindowMessage(message);
        }
        

        [DllImport("user32")]
        public static extern bool PostMessage(IntPtr hwnd, int msg, IntPtr wparam, IntPtr lparam);

        [DllImportAttribute("user32.dll")]
        public static extern bool ShowWindow(IntPtr hWnd, int nCmdShow);

        [DllImportAttribute("user32.dll")]
        public static extern bool SetForegroundWindow(IntPtr hWnd);

        public static void ShowToFront(IntPtr window)
        {
            //Show window and display in front   
            ShowWindow(window, SW_SHOWNORMAL);
            SetForegroundWindow(window);
        }
    }
}

Now in your main application form [Here Form1], i will override Form class method WinProc.

protected override void WndProc(ref Message message)
{
    if (message.Msg == Program.WM_SHOWFIRSTINSTANCE)
    {
        ShowWindow();
    }
    base.WndProc(ref message);
}

Also in your main form, override Form closing event, and cancel event and show form in taskbar. So actually form is not closed when user clicks on close icon.

protected override void OnFormClosing(FormClosingEventArgs e)
{
    e.Cancel = true;
    Hide();
}

I hope that you will now get basic idea how to implement logic to make application as singleton.

15 comments:

  1. It's Really A Great Post. Looking For Some More Stuff.



    shriram break free

    ReplyDelete

  2. The post was good and really helpful for more stuff click on the link below.
    Shriram earth off mysore road

    ReplyDelete
  3. The post was really very good.Thanks for sharing
    prestige elysian

    Prestige elysian

    ReplyDelete
  4. I really enjoyed your blog Thanks for sharing such an informative post.Looking For Some More Stuff.

    shuttering works

    ReplyDelete
  5. This is an awesome post.Really very informative and creative contents about Java. These concept is a good way to enhance the knowledge.I like it and help me to development very well.Thank you for this brief explanation and very nice information.Well, got a good knowledge



    oracle training in chennai

    oracle training in annanagar

    oracle dba training in chennai

    oracle dba training in annanagar

    ccna training in chennai

    ccna training in annanagar

    seo training in chennai

    seo training in annanagar

    ReplyDelete
  6. I thoroughly enjoyed reading your article on clean code principles, and I appreciate the clarity with which you explained the concepts. Your insights into writing maintainable and efficient code are invaluable for developers at all levels. The examples provided were insightful and made it easy to grasp the principles you discussed.

    In addition to the clean code principles you highlighted, I would like to commend Imarticus Learning's Data Science Course for its excellence in providing a comprehensive understanding of data science concepts. The course's practical approach and hands-on projects are particularly commendable, helping learners apply theoretical knowledge to real-world scenarios. The instructors' expertise and the course structure ensure that students are well-equipped to tackle challenges in the dynamic field of data science. I believe that combining the principles of clean code with a solid foundation in data science from Imarticus Learning's course can empower developers to create efficient, maintainable, and cutting-edge solutions.

    ReplyDelete
  7. Thank you for sharing your ideas with us. It was very informative to me. Every point is clearly described. Advanced Data Science training in Chandigarh

    ReplyDelete