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.

16 comments:

  1. Very nice post here and thanks for it .I always like and such a super contents of these post.Excellent and very cool idea and great content of different kinds of the valuable information's.

    selenium Training in Chennai

    amazon web services Training in Chennai

    rpa Training in Chennai

    ReplyDelete
  2. Thanks for the informative article. This is one of the best resources I have found in quite some time. Nicely written and great info. I really cannot thank you enough for sharing.

    rpa Training in Chennai

    rpa Training in bangalore

    rpa Training in pune

    blueprism Training in Chennai

    blueprism Training in bangalore

    blueprism Training in pune

    rpa online training

    ReplyDelete
  3. Hey, Wow all the posts are very informative for the people who visit this site. Good work! We also have a Website. Please feel free to visit our site. Thank you for sharing.Well written article Thank You Sharing with Us pmp training Chennai | pmp training centers in Chenai | pmp training institutes in Chennai | pmp training and certification in Chennai | pmp training in velachery

    ReplyDelete
  4. This information is impressive. I am inspired with your post writing style & how continuously you describe this topic. Eagerly waiting for your new blog keep doing more.
    AWS Training in Chennai
    aws training in bangalore
    AWS Course in Chennai
    aws course in bangalore
    AWS Training centers in Chennai
    aws certification training in bangalore

    ReplyDelete
  5. Such an excellent and interesting blog, do post like this more with more information, this was very useful, Thank you.
    Aviation Academy in Chennai
    Aviation Courses in Chennai
    best aviation academy in chennai
    aviation training in chennai

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



    shriram break free

    ReplyDelete

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

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

    Prestige elysian

    ReplyDelete
  9. Information provided by you is very helpful and informative. Keep On updating such information.

    prestige elysian


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

    shuttering works

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

    best seo company in bangalore SSS digital Marketing

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

    shuttering works

    ReplyDelete