Single Instance Form

M

Mark Jerde

VS 2005. When I google "CSharp single instance form" the returned pages
usually use a Mutex or the VB.NET runtime library.
http://en.csharp-online.net/Applica..._2.0—Single-Instance_Detection_and_Management
http://www.codeproject.com/csharp/SingleInstanceApplication.asp
http://blogs.msdn.com/onoj/archive/2004/06/04/148532.aspx

"Program.cs" below seems to work fine. A feature is it restores a minimized
form. Is this code ok or is there a "gotcha"? I'm aware it's probably
slower than a Mutex but restoring the minimized form is nice.

Thanks.

-- Mark

========== Program.cs =========

using System;
using System.Collections.Generic;
using System.Windows.Forms;
using System.Runtime.InteropServices;
using System.Diagnostics;
using System.Reflection;

namespace OneInstance {
internal static class Program {
/// <summary>
/// The main entry point for the application.
/// </summary>
///
///
[STAThread]
public static void Main() {
//Get the running instance.
Process instance = RunningInstance();

if (instance == null) {
//If no other instance of program is running, show form
Application.Run(new Form());
} else {
//There is another instance of this process, do not allow
second
HandleRunningInstance(instance);
MessageBox.Show("Program already running! \n Focus
returned", "Already Open",
MessageBoxButtons.OK,
MessageBoxIcon.Exclamation);
}
}

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
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 process;
}
}
return null;
}

public static void HandleRunningInstance(Process instance) {
//Make sure the window is not minimized or maximized
ShowWindowAsync(instance.MainWindowHandle, WS_SHOWNORMAL);

//Set the real intance to foreground window
SetForegroundWindow(instance.MainWindowHandle);
}

[DllImport("User32.dll")]
private static extern bool ShowWindowAsync (IntPtr hWnd, int
cmdShow);

[DllImport("User32.dll")]
private static extern bool SetForegroundWindow(IntPtr hWnd);

private const int WS_SHOWNORMAL = 1;
}
}
 
P

PokerMan

Why not use a singleton pattern, its specifically for single instance only
classes.
 
M

Mark Jerde

This was a project written by a college student who works for us part time.
I wanted the MS Outlook feature of restoring a minimized form. This is his
solution and I'm just wondering if anyone sees something that won't work all
the time.

-- Mark

PokerMan said:
Why not use a singleton pattern, its specifically for single instance only
classes.

Mark Jerde said:
VS 2005. When I google "CSharp single instance form" the returned pages
usually use a Mutex or the VB.NET runtime library.

http://en.csharp-online.net/Applica..._2.0—Single-Instance_Detection_and_Management
http://www.codeproject.com/csharp/SingleInstanceApplication.asp
http://blogs.msdn.com/onoj/archive/2004/06/04/148532.aspx

"Program.cs" below seems to work fine. A feature is it restores a
minimized form. Is this code ok or is there a "gotcha"? I'm aware it's
probably slower than a Mutex but restoring the minimized form is nice.

Thanks.

-- Mark

========== Program.cs =========

using System;
using System.Collections.Generic;
using System.Windows.Forms;
using System.Runtime.InteropServices;
using System.Diagnostics;
using System.Reflection;

namespace OneInstance {
internal static class Program {
/// <summary>
/// The main entry point for the application.
/// </summary>
///
///
[STAThread]
public static void Main() {
//Get the running instance.
Process instance = RunningInstance();

if (instance == null) {
//If no other instance of program is running, show form
Application.Run(new Form());
} else {
//There is another instance of this process, do not allow
second
HandleRunningInstance(instance);
MessageBox.Show("Program already running! \n Focus
returned", "Already Open",
MessageBoxButtons.OK,
MessageBoxIcon.Exclamation);
}
}

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
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 process;
}
}
return null;
}

public static void HandleRunningInstance(Process instance) {
//Make sure the window is not minimized or maximized
ShowWindowAsync(instance.MainWindowHandle, WS_SHOWNORMAL);

//Set the real intance to foreground window
SetForegroundWindow(instance.MainWindowHandle);
}

[DllImport("User32.dll")]
private static extern bool ShowWindowAsync (IntPtr hWnd, int
cmdShow);

[DllImport("User32.dll")]
private static extern bool SetForegroundWindow(IntPtr hWnd);

private const int WS_SHOWNORMAL = 1;
}
}
 
J

Jon Skeet [C# MVP]

PokerMan said:
Why not use a singleton pattern, its specifically for single instance only
classes.

Singletons work within a process - the OP wants to ensure that when a
second process starts, it restores the first process's window. The
singleton pattern can't help with that at all.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top