Issues with multiple instances

G

Guest

Hi,

I am pretty new to c# development / compact frame work so if this is a dumb
question I appologise.

I have a application that has multiple forms, the main form owns and
launches a splash screen, then once the loading is all done I ditch the
splash screen.

My problem is that during the start up it is possible for me to launch
multiple instances of my application.

I am quiet unsure why this is happening, I am doing the main loading of my
applications engine in the method called from the forms load event. It seems
that up to a certain point it is possible to create a new instances of the
application, but then after a certain point it brings the loaded instance to
the foreground rather than creating a new one.

I have been looking into a few ways to try and solve this and am familiair
with using named mutexes in other languages but it seems that this isn't
supported.
How is it possible to complish this in C# using the compact framework API.
I've tried using the method call

iMutex.WaitOne();

but all this does is stack up instances of my application until the current
application is killed.

I've seen a few postings in the news groups about using unmanaged code to
create the mutex, is this really the only solution ?

I hope my posting is clear and someone out there can explain where I am
going wrong.

thanks in advance

Guus Davidson
 
G

Guest

Thanks for your reply Daniel,

I am still a bit confused, you state that the single instance behavior is
default in the windows mobile platform.
Can you answer how I would have broken this so that during the first few
seconds of start up it is possible to start up another instance?

The application I am working on was written by another developer, I'm just
trying to fix the dirty coding ;-)

thanks in advance
Guus Davidson
 
G

Guest

The CF enforces it, but if you get into the CF initialization before it does
it's check, you can get multiple instances. Add a mutex check at the start
of the app and handle the second instance there (which is how it should be
set up in the first place IMHO).

-Chris
 
G

Guest

Hi,

I have implemented a named mutex as suggested in one of the earlier
postings, but I am still able to create multiple instances of my application.


I have added in a log4net logging framework to see if it will help me track
down where the issue is.
I have my logging setup so that it should just append to the log file.

I have set up my application so that on the device it can be started by
pressing one of the hardware buttons.
My test here is to press the button a couple of times and then while
everything is loading up check out the "running applications".

From my log file I am only ever seeing one entry point into the "Main"
method, yet I can clearly see that there are several instances of my
application running in the running application list.

I have enclosed the relivent code snippets from my application, could anyone
tell me what I am doing wrong ?

thanks in advance

Guus Davidson

<Code Snippet from my application>

//My main method using the IsInstanceMethod, this creates a named mutex is
one doen't exist.
//I am passing back a reference to metex handle so I can release the mutex
when I am finished.
//I have added in log4net and am using a singleton logger within my
application.

static void Main()
{
iLog.Info("Main");
int mutexhandle = 0;
if (!IsInstanceRunning(ref mutexhandle))
{
// just making a local copy due to threading fears
int mutexhnd = mutexhandle;
// Wait until it is safe to enter.

if (IsActivateProperly())
{
Application.Run(new MainForm());
}
else
{
Application.Run(new RegistrationForm());
}
if (ReleaseMutex(mutexhnd))
{
iLog.Info("mutex released");
}
}
iLog.Info("~Main");
}

//MainForm constructor, the bugs comment isn't mine its dirty coding and
needs removed.

public MainForm()
{
iLog.Info("MainForm constructor");

this.Enabled = false;

//bugs: it will throw an ArgumentException given the app.config file is not
in place
System.Threading.Thread.Sleep(500);
InitializeComponent();
iLog.Info("~MainForm constructor");
}

//My Splash screen start method, called as a result of the splashFormThread
in the MainForm_Load

public void StartSplash()
{
iLog.Info("StartSplash");
if (iSplashForm == null)
{
iSplashForm = new SABannerForm();
}
iLog.Info("running splash");
Application.Run(iSplashForm);
iLog.Info("~running splash");
iLog.Info("~StartSplash");
}

private void CloseSplash(object stateinfo)
{
iLog.Info("CloseSplash");
if (iSplashForm != null)
{
iLog.Info(iClassName + " Closing splash form");
// Shut down the splash screen
iSplashForm.Invoke(new EventHandler(iSplashForm.KillMe));
iSplashForm.Dispose();
iSplashForm = null;
}
iLog.Info("~CloseSplash");
}

private void MainForm_Load(object sender, System.EventArgs e)
{
iLog.Info("MainForm_Load");
try
{
#region start the splash screen
iLog.Info("Start Splash Thread");
Thread splashFormThread = new Thread(new ThreadStart(StartSplash));
splashFormThread.Priority = ThreadPriority.AboveNormal;
splashFormThread.Start();
#endregion

#region initialize all my other stuff is set up here
..
..
..
..

}
catch (Exception ex)
{
iExhandler.Error("MainForm: " + ex.ToString());
}
iLog.Info("~MainForm_Load");
}

// editied version of a method found on form somewhere
// thought I need to releasethe mutex once I've created it so am passing
back the handle
public static bool IsInstanceRunning(ref int aMutexHandle)
{
string appname =
System.Reflection.Assembly.GetExecutingAssembly().GetName().Name;
iLog.Info(appname + "IsInstanceRunning");
aMutexHandle = CreateMutex(IntPtr.Zero, true, appname);
bool result = false;
if (aMutexHandle != 0)
{
if (GetLastError() == ERROR_ALREADY_EXISTS)
{
iLog.Info(appname + " application does exist");
result = true;
}
}
iLog.Info(appname + "~IsInstanceRunning");
return result;
}
 
D

Daniel Moth

I haven't looked at all your code but, just in case, you do realise that
running programs shows all top level captioned windows in your application
right? To see the number of processes use the Remote Process Viewer tool
from the start menu.

Also if you are genuinely observing this behaviour start building a repro.
Start a new project from scratch and try to replicate it in there adding
bits of code from your original project (especially important since you
didn't write the original code).

Cheers
Daniel
 
G

Guest

If you're using a named mutex properly, I can't see how it's possible to
have multiple instances running. Show us some code. "Running Programs"
shows all top-level windows (so all forms) in your app - not actual
processes.
 
P

Paul G. Tobey [eMVP]

There was a report like this in, I think, the last Windows CE chat. It
appears that it might be a problem with using CreateMutex( NULL, TRUE,
name ). It seemed that the poster was saying that he was able to do this in
two programs and get something other than ERROR_ALREADY_EXISTS from both. I
was expecting him to post the repro here, but I didn't see anything wrong
with the code and suggested that he try getting the mutex without trying to
take ownership and use WaitForSingleObject() to get it, timing out and
exiting if that didn't return in a second or two.

Paul T.
 
G

Guest

I'd definitely like to see a repro of that. Your suggested route is
definitely a safe workaround (though I'd think the first would be safe too).
 

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