main(array<System::String ^> ^args)Hi,
The following code works fine when debugging, only one instance of the application is started. However, when I build a release version of the code multiple instance of the app are allowed to run. ie MutexCreated is always returned as true.
I have tried all combinations of InitalOwner and Testing both MutexCreated and trying to lock the mutex following its creation. All work exactly as I would expect on a debug build but when switching to a release build all instances of the app will get the mutex lock.
Help/ advice please!!
Andrew
int
{
bool InitalOwner=true;
bool MutexCreated=false;
Mutex^ Mut = gcnew Mutex(InitialOwner,"Global\\MyAppMutex",MutexCreated);
if ( MutexCreated==true )
// Also tried if ( Mut->WaitOne(10,false) ) {// Enabling Windows XP visual effects before any controls are created
Application::EnableVisualStyles();
// Create the main window and run itApplication::Run(
gcnew Form1());}
else{
MessageBox::Show(
"Application is already running.","My App");}
return 0;}

Single Instance of App only works when debugging (Mutex Problem) C++
Asen Asenov
Using WinObj The mutex does not appear in the BaseNamedObject list for the release build. (The mutex created flag in the code is however set to true) This explains why the app always thinks its the first instance.
The mutex appears in the BaseNamedObject list for the debug build and handles are incremented correctly.
I have created a new windows.forms app to test the mutex it works fine.
A thought - This app started its life as a Visual C++ Express app a couple of months before VS2005 was released. As soon as VS2005 was released all development was switched to it. Could there be a compile/link time option introduced by Express that is now confusing the code in some way
I realise that commenting out the app.run should not make the problem go away but it does. The App introduces various new namespaces could these be effecting the domain of the mutext
As for cleaning up the mutex - I have assumed that garbage collection would tidy it up. It does appear to do so for the test app. (ie the mutex disappears from the BaseNamedObjects list when the last app closes.)
KeFei Wang
The mutex works properly for me. Are you using separate user accounts to run the differing programs under
Michael Taylor - 3/1/06
Target Su.
Ok, tried that it works fine for both debug and release versions.
I have also found the if I replace the line
Application::Run(
gcnew Form1());with
while(true) {int x=0;x++;}
The app now works as expected when compiled for both debug and release. ( it is a bit dull to watch though!)
It appears there is something about the release version of the libraries or the release options that I am using that is confusing the mutex.
Help still stuck!
Scott1978
Just so Andrew doesn't think he is the only one that encountered this problem, I thought I would mention that I am having the same experience in a C# program built with VS 2005. The debug version works correctly, but the released version creates the mutex every time, even if it already exists.
Vanni Torelli
I agree thanks for you time.
Andrew
David Schulze
No - All are being run under the same user account.
It fails if each instance is run from the desktop or by starting multiple instances from within Visual Studio.
Other than checking for instances of the process running, which will only work if the user has admin priviledges can anyone think of another approach
tbrauer
There's no switch I'm aware of that should cause the problem you're seeing. Nevertheless I guess if you somehow managed to get it to use the single-threaded CRT it might have a problem but this shouldn't even be a problem. Maybe there is a problem with it trying to load the wrong binaries or something. Nevertheless I'd just transfer all your classes over to the new project and be done with it. Debugging problems with beta software just isn't worth the effort if you can work around it in my opinion.
Michael Taylor - 3/2/06
tonyr1977
chachu207
Ok, it's time to get nasty. Something is definitely not right. You aren't manipulating the mutex anywhere else in your code are you (say the form)
Try this:
1) Start the first instance of your app outside the debugger.
2) Run winobj from SysInternals (http://www.sysinternals.com/Utilities/WinObj.html)
3) Under BaseNamedObjects you should see your mutex. The handle count should be 1.
4) Start another instance of your app. Check the handle count again. The handle count should be 2 because each app has a reference to the mutex.
Note that commenting out the Application.Run call shouldn't have had any impact since the second instance should never even get into the loop. Also note that a mutex is a disposable object so you should be sure to clean it up before your app exits. Otherwise it is possible for you to orphan a global system object which wouldn't be good.
Michael Taylor - 3/2/06
jesc
Using mutexes and other named sync objects is standard practice for detecting multiple instances of an app. It is done all the time and I've personally done it on more than one occasion both inside .NET and out. Therefore there has to be something not quite right with your code.
Take the following code and drop it into a C++ console app and verify it works under the circumstances you have.
#include
"stdafx.h"using
namespace System;using
namespace System::Threading;int
main(array<System::String ^> ^args){
bool created = false;Mutex^ mutex =
gcnew Mutex(true, "Global\\TestMutex", created); if (created)Console::WriteLine(
"Created mutex."); elseConsole::WriteLine(
"Mutex already exists.");Console::ReadLine();
return 0;}
Michael Taylor - 3/1/06