Sign in to follow this  
Moe

Preventing multiple instances of an application from starting...

Recommended Posts

Some time ago, when I was creating Todo 3.0 (a handy to-do list program for Windows), I needed a way to prevent users from starting multiple instances of an application. The reason for doing so is that if a user made changes to his/her to-do list in one instance of the application, then switched to another instance of the same application and made changes, the changes would overwrite each other. I figured this behaviour would probably confuse the user, and that it would be a better idea of the user could only have one instance of the application open at any given time. I did a little bit of digging around and thought of a few ways this could be done:
  1. Have the application open a file for reading/writing. If the application fails to open the file because it is already open, then an instance of the application must already be running.
  2. Use a named mutex. When starting the application, check to see if a mutex exists with a particular name. If it does, that means the application is already running.
Naturally, I chose the second approach. It seemed a bit more elegant and foolproof. Now that I have been thinking about it, I am wondering, what other ways are there that this could have been done? Is creating a named mutex a safe approach to solving this problem? The reason I ask is that I wouldn't mind writing up a short "Sweet Snippet" type article for GameDev on the subject (how to prevent multiple instances of an application from starting in the .Net environment), but I do want to make sure that what I am doing is indeed appropriate. Anyone?

Share this post


Link to post
Share on other sites
From an app I wrote:

// Create mutex
m_hEvent = CreateEvent(NULL, FALSE, FALSE, "DruinkIMMutexName");
if(!m_hEvent)
{
// Error
}
else if(GetLastError() == ERROR_ALREADY_EXISTS)
{
CloseHandle(m_hEvent);
m_hEvent = NULL;

// Application already running
}
else
{
// Application not already running
}


And then at cleanup:

CloseHandle(m_hEvent);
m_hEvent = NULL;


m_hEvent is a HANDLE

Share this post


Link to post
Share on other sites
or, you could do this nasty trick i found somewhere ;)

[source lang='csharp']
if (Path.GetFileName(Application.ExecutablePath).ToLower() != "myprogram.exe")
{
MessageBox.Show(null, "Please rename this program to myprogram.exe (don't mind the caps)!",
"I WAS RENAMED!:(",
MessageBoxButtons.OK, MessageBoxIcon.Error);
return;
}
System.Diagnostics.Process[] p1 = System.Diagnostics.Process.GetProcessesByName("myprogram");
if (p1.Length > 1)
{
MessageBox.Show(null, "Only one instance of this program can run at a time. Please shut down the other instance!",
"Another instance of this program is currently running",
MessageBoxButtons.OK, MessageBoxIcon.Error);
return;
}




ugly hack but should work...

Share this post


Link to post
Share on other sites
Quote:
Original post by Colin Jeanne
The named mutex is a pretty standard approach. I'm not sure what you mean by "safe", however. As with all single instance programs, someone could potentially write another program to deny the use of your program (see Raymond Chen's article). Is that what you mean?

Exactly. I hadn't thought of that, and it really helps to be aware of such issues.

Evil Steve: That does look like a decent solution. I suppose it really isn't too different than using a named mutex.

cobru: That does seem like a bit of an ugly hack.

SiCrane: You have a mind like a whip! I had forgotten about that. Rather than focussing on passing data between instances of an app, I'd rather just focus on preventing multiple instances of an app.

Share this post


Link to post
Share on other sites
A cheap method is to use "FindWindow" to find a window of your classname,if one is found then your application is already running,
ofc this one works only if your app has a window so it isnt for consol app.

Share this post


Link to post
Share on other sites
Article also covers single instances:

// SingleInstanceApplication.cs
class SingleInstanceApplication : WindowsFormsApplicationBase {

// Must call base constructor to ensure correct initial
// WindowsFormsApplicationBase configuration
public SingleInstanceApplication() {

// This ensures the underlying single-SDI framework is employed,
// and OnStartupNextInstance is fired
this.IsSingleInstance = true;
}
}

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this