Click here to Skip to main content
Rate this: bad
good
Please Sign up or sign in to vote.
See more: C# WPF
I use this snippet to detect if an instance of my application is already running.
 
public static Process RunningInstance()  
 {  
    Process current = Process.GetCurrentProcess();  
    Process[] processes = Process.GetProcessesByName (current.ProcessName);  
  
     //Loop through the running processes in with the same name  
     foreach (Process process in processes)  
     {  
        //Ignore the current process  
         if (process.Id != current.Id)  
        {  
            //Make sure that the process is running from the exe file.  
             if (Assembly.GetExecutingAssembly().Location.Replace("/", "\\") == current.MainModule.FileName)  
             {  
                //Return the other process instance.  
                return process;  
             }  
         }  
     }  
     //No other instance was found, return null.  
     return null;  
 }  
 
However, I was thinking, is there a way to parse send the arguments in the current process to the already running process. Like in an app that adds files, I would like to kill the new process but send it's arguments to the already running process.
Posted 17-Aug-12 4:36am
Comments
Arun (Multithreaded) at 17-Aug-12 10:14am
   
Are you want to prevent multiple execution of a same C# app?
geekbond at 18-Aug-12 10:37am
   
Yeah, something like that but get the arguments of the current instance sent to the already running instance.
Rate this: bad
good
Please Sign up or sign in to vote.

Solution 1

There are many ways to do this (look up IPC mechanisms for .NET). But an increasingly common mechanism is to use WCF with named pipes. The file name is passed from the 2nd instance to the 1st instance and then the 2nd instance quits. The 1st instance knows what to do with the passed in file name (typically just open it).
  Permalink  
Comments
geekbond at 17-Aug-12 10:24am
   
Do you have any links that I can start from? Much appreciated.
Nish Sivakumar at 17-Aug-12 10:42am
   
See http://www.codeproject.com/Articles/62934/Many-to-One-Local-IPC-using-WCF-and-NetNamedPipeBi
geekbond at 17-Aug-12 11:09am
   
Thank you.
Nish Sivakumar at 17-Aug-12 11:23am
   
No problem.
Mika Wendelius at 17-Aug-12 16:49pm
   
Nice!
Sergey Alexandrovich Kryukov at 17-Aug-12 17:35pm
   
I have more specific, detailed and functional method, please see my solution -- it's pretty interesting.
--SA
Rate this: bad
good
Please Sign up or sign in to vote.

Solution 2

This is not a good method of detecting it. You should understand, that it's always possible that some unrelated applications can have the same name or other attributes.
 
Here is my method:
 
Use "classical" remoting based on IPC channel. Such channel uses named pipes for communication. I usually use a full file name of the location of the main executable module as a name of the channel. This way, your name is unique enough, but the same application copied in another location is considered as a different application. To me, this is fine. You can use some other unique ID, such a the one obtained from the unique name of the signed application, with very good probability of uniqueness (this strong name is even used for uniqueness in the scope of world. Another unique value can be some GUID hard-coded in the assembly or put in resources.
 
Now, your application should be able to play the role of both server and client part. First, it tries to put the role of the client part and connect to the server part. It if fails, the application is considered to be the only instance, and now it should act as a server. If connection is successful, this is the second instance. This second instance should use remoting via a remote object to pass, say, command-line parameter to the fist instance. The first instance's remote object accept parameters and tries to use them (for example, load more files; this is the most typical application). Also, you may want to activate the UI of the first instance, through activation of the main window or main form of the first instance. When the second instance of the application passes all the data, it close the connection and terminate itself immediately.
 
Results: you have only one instance of the application permanently working, others executes for a short time only, just to check in and optionally pass some data to the first instance.
 
—SA
  Permalink  
Comments
geekbond at 18-Aug-12 9:31am
   
That's a very good idea, thank you.
Sergey Alexandrovich Kryukov at 18-Aug-12 12:12pm
   
You are welcome.
If so, please accept if formally (green button) -- thanks.
--SA
Rate this: bad
good
Please Sign up or sign in to vote.

Solution 3

There are ways to do with few classes....
 
We can create a simple class to postmessage and related stuffs as :
static public class WinApi
   {
       [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);
       }
 
       public const int HWND_BROADCAST = 0xffff;
       public const int SW_SHOWNORMAL = 1;
 
       [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)
       {
           ShowWindow(window, SW_SHOWNORMAL);
           SetForegroundWindow(window);
       }
   }
 
The after we need create a class to determine instances using the PostMessage...
 
static public class SingleInstance
    {
        public static readonly int WM_SHOWFIRSTINSTANCE =
            WinApi.RegisterWindowMessage("WM_SHOWFIRSTINSTANCE|{0}", ProgramInfo.AssemblyGuid);
        static Mutex mutex;
        static public bool Start()
        {
            bool onlyInstance = false;
            string mutexName = String.Format("Local\\{0}", ProgramInfo.AssemblyGuid);
 
            // if you want your app to be limited to a single instance
            // across ALL SESSIONS (multiple users & terminal services), then use the following line instead:
            // string mutexName = String.Format("Global\\{0}", ProgramInfo.AssemblyGuid);

            mutex = new Mutex(true, mutexName, out onlyInstance);
            return onlyInstance;
        }
        static public void ShowFirstInstance()
        {
            WinApi.PostMessage(
                (IntPtr)WinApi.HWND_BROADCAST,
                WM_SHOWFIRSTINSTANCE,
                IntPtr.Zero,
                IntPtr.Zero);
        }
        static public void Stop()
        {
            mutex.ReleaseMutex();
        }
    }
 
Create a class that fetch app guid:
 
static public class ProgramInfo
    {
        static public string AssemblyGuid
        {
            get
            {
                object[] attributes = Assembly.GetEntryAssembly().GetCustomAttributes(typeof(System.Runtime.InteropServices.GuidAttribute), false);
                if (attributes.Length == 0)
                {
                    return String.Empty;
                }
                return ((System.Runtime.InteropServices.GuidAttribute)attributes[0]).Value;
            }
        }
 
    }
 

Now we can modify the entry point as :
 
/// <summary>
/// The main entry point for the application.
/// </summary>
[STAThread]
static void Main()
{
 
    if (!SingleInstance.Start())
    {
        SingleInstance.ShowFirstInstance();
        return;
    }
 
    Application.EnableVisualStyles();
    Application.SetCompatibleTextRenderingDefault(false);
 
    try
    {
 
        Form1 mainForm = new Form1();
        Application.Run(mainForm);
    }
    catch (Exception e)
    {
        MessageBox.Show(e.Message);
    }
 
    SingleInstance.Stop();
 
}
 
Now need to add few methods to Form1(the intitial form that run from entry point:
 

protected override void WndProc(ref Message message)
{
    if (message.Msg == SingleInstance.WM_SHOWFIRSTINSTANCE)
    {
        ShowWindow();
    }
    base.WndProc(ref message);
}
 
public void ShowWindow()
{
    // Insert code here to make your form show itself.
    WinApi.ShowToFront(this.Handle);
}
  Permalink  
v2
Comments
geekbond at 18-Aug-12 9:33am
   
That works fine for Window app. Only wish there was a way to send the arguments of the new instance to the already running instance. Thanks though.
Kuthuparakkal at 18-Aug-12 11:01am
   
May this help you
Courtesey: http://stackoverflow.com/questions/3793997/pass-arguments-to-running-application
 
static class Program
{
[STAThread]
static void Main(params string[] Arguments)
{
SingleInstanceApplication.Run(new ControlPanel(), NewInstanceHandler);
}
 
public static void NewInstanceHandler(object sender, StartupNextInstanceEventArgs e)
{
string imageLocation = e.CommandLine[1];
MessageBox.Show(imageLocation);
e.BringToForeground = false;
ControlPanel.uploadImage(imageLocation);
}
 
public class SingleInstanceApplication : WindowsFormsApplicationBase
{
private SingleInstanceApplication()
{
base.IsSingleInstance = true;
}
 
public static void Run(Form f, StartupNextInstanceEventHandler startupHandler)
{
SingleInstanceApplication app = new SingleInstanceApplication();
app.MainForm = f;
app.StartupNextInstance += startupHandler;
app.Run(Environment.GetCommandLineArgs());
}
}
}
geekbond at 22-Aug-12 10:00am
   
Much appreciated. Thanks a lot.
geekbond at 28-Aug-12 13:27pm
   
Any ideas on how to achieve this in WPF? works perfectly in WinForms but I'm in a fix on how to make it work in WPF, any help would be appreciated.

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

  Print Answers RSS
0 OriginalGriff 240
1 Kamal Rocks 184
2 PIEBALDconsult 150
3 BillWoodruff 148
4 Jochen Arndt 135
0 OriginalGriff 5,695
1 DamithSL 4,506
2 Maciej Los 4,007
3 Kornfeld Eliyahu Peter 3,480
4 Sergey Alexandrovich Kryukov 3,180


Advertise | Privacy | Mobile
Web02 | 2.8.141216.1 | Last Updated 18 Aug 2012
Copyright © CodeProject, 1999-2014
All Rights Reserved. Terms of Service
Layout: fixed | fluid

CodeProject, 503-250 Ferrand Drive Toronto Ontario, M3C 3G8 Canada +1 416-849-8900 x 100