Single instance of app

S

Steve Barnett

I want to ensure that there is only ever one instance of my app running on a
single PC at any time. I understand that I can achieve this by using a mutex
and, if I can't take ownership of the mutex, I know there is another
instance of my program running.

Problem is, how do I get the "new" instance to communicate with the "old"
instance? The new one will have been started with a command line parameter
that I want to pass to the old instance for execution. In my VB6 days, I did
this using DDE (old, but safe).

What's the C# equivalent?

Can you point me at the classes I might need to work with please (No
detailed code, please - I'm trying to learn this stuff for myself).

Thanks
Steve
 
?

=?iso-8859-1?Q?J=E9r=F4me_Bonnet?=

Hi,

it's quite simple thanks to .net framework which provides everything you need ;-)

using System.Diagnostics;

public static bool IsOneInstance()
{
Process pcur = Process.GetCurrentProcess();
Process[] ps = Process.GetProcesses();
foreach( Process p in ps )
{
if ( pcur.Id != p.Id )
if ( pcur.ProcessName == p.ProcessName )
return false;

}
return true;
}
Jey
 
S

Steve Barnett

Thank you
Steve
Hi,

it's quite simple thanks to .net framework which provides everything you need ;-)

using System.Diagnostics;

public static bool IsOneInstance()
{
Process pcur = Process.GetCurrentProcess();
Process[] ps = Process.GetProcesses();
foreach( Process p in ps )
{
if ( pcur.Id != p.Id )
if ( pcur.ProcessName == p.ProcessName )
return false;

}
return true;
}
Jey
 
P

Peter Kirk

Jérôme Bonnet said:
using System.Diagnostics;
public static bool IsOneInstance()
{
Process pcur = Process.GetCurrentProcess();
Process[] ps = Process.GetProcesses();
foreach( Process p in ps )
{
if ( pcur.Id != p.Id )
if ( pcur.ProcessName == p.ProcessName )
return false;

}
return true;
}

Would it be possible for two of your processes to start almost
simultaneously, detect each other, return false from this method - and
therefore both terminate?
 
N

Nicholas Paldino [.NET/C# MVP]

Unfortunately, this is a incredibly inefficient way of doing this, and not accurate, either.

If you are using .NET 2.0, derive a class from the WindowsFormsApplicationBase class in the Microsoft.VisualBasic.ApplicationServices namespace (in Microsoft.VisualBasic.dll). There is a protected property in that class named IsSingleInstance. Set it to true in your derived class (in the constructor).

Then, you can call the Run method on your derived class like you would call the Run method on the Application class. It will then run your program.

Additionally, you can sign up for the StartupNextInstance event (or override your OnStartupNextInstance method in your derived class). This is called when another instance of your app is started. The event, however, fires in the instance that is already running. The WindowsFormsApplicationBase takes care of the interprocess communication for you.

If you are not using .NET 2.0, you should use a Mutex with a unique name (I find that the assembly qualified type name is a good unique name) and try and get access to it. If you can not, then you know that another instance of your app is running.

If you want the first app to know the second app was started up (unsuccessfully), then you will have to create an interprocess communication mechanism (such as remoting, which is what WindowsFormsApplicationBase uses, but it uses the new IPC channel, which uses named pipes, which is more efficient than the TCP or HTTP channels) to communicate that information to the original application.

Hope this helps.


--
- Nicholas Paldino [.NET/C# MVP]
- (e-mail address removed)
Hi,

it's quite simple thanks to .net framework which provides everything you need ;-)

using System.Diagnostics;

public static bool IsOneInstance()
{
Process pcur = Process.GetCurrentProcess();
Process[] ps = Process.GetProcesses();
foreach( Process p in ps )
{
if ( pcur.Id != p.Id )
if ( pcur.ProcessName == p.ProcessName )
return false;

}
return true;
}
Jey
 
S

Steve Barnett

That's great, thank you.

For no rational reason, I think I'll go for the mutex/IPC route. I believe I'll get more learning out of that and I won't have to admit that VB users have something that C# users need!

Steve

Unfortunately, this is a incredibly inefficient way of doing this, and not accurate, either.

If you are using .NET 2.0, derive a class from the WindowsFormsApplicationBase class in the Microsoft.VisualBasic.ApplicationServices namespace (in Microsoft.VisualBasic.dll). There is a protected property in that class named IsSingleInstance. Set it to true in your derived class (in the constructor).

Then, you can call the Run method on your derived class like you would call the Run method on the Application class. It will then run your program.

Additionally, you can sign up for the StartupNextInstance event (or override your OnStartupNextInstance method in your derived class). This is called when another instance of your app is started. The event, however, fires in the instance that is already running. The WindowsFormsApplicationBase takes care of the interprocess communication for you.

If you are not using .NET 2.0, you should use a Mutex with a unique name (I find that the assembly qualified type name is a good unique name) and try and get access to it. If you can not, then you know that another instance of your app is running.

If you want the first app to know the second app was started up (unsuccessfully), then you will have to create an interprocess communication mechanism (such as remoting, which is what WindowsFormsApplicationBase uses, but it uses the new IPC channel, which uses named pipes, which is more efficient than the TCP or HTTP channels) to communicate that information to the original application.

Hope this helps.


--
- Nicholas Paldino [.NET/C# MVP]
- (e-mail address removed)
Hi,

it's quite simple thanks to .net framework which provides everything you need ;-)

using System.Diagnostics;

public static bool IsOneInstance()
{
Process pcur = Process.GetCurrentProcess();
Process[] ps = Process.GetProcesses();
foreach( Process p in ps )
{
if ( pcur.Id != p.Id )
if ( pcur.ProcessName == p.ProcessName )
return false;

}
return true;
}
Jey
 
S

Steve Barnett

Peter Kirk said:
Jérôme Bonnet said:
using System.Diagnostics;
public static bool IsOneInstance()
{
Process pcur = Process.GetCurrentProcess();
Process[] ps = Process.GetProcesses();
foreach( Process p in ps )
{
if ( pcur.Id != p.Id )
if ( pcur.ProcessName == p.ProcessName )
return false;

}
return true;
}

Would it be possible for two of your processes to start almost
simultaneously, detect each other, return false from this method - and
therefore both terminate?

This is why I want to go with a Mutex, as it should take care of this
situation. In reality, it's unlikely that a user could start two copies that
fast - they'll typically be double clicking on files in Explorer. I just
never imagined it would get so complicated - I did this in a couple of lines
of ode in VB6.

Steve
 
S

Steve Barnett

I've been trying to do this all afternoon. The code looks Ok and I'm getting
a single instance of my app started, but I'm also getting an "Abandoned
Mutex Exception" generated when my app closes. I've had a look on
CodeProject.Com and it appears that this is probably a problem with the .Net
2.0 Beta 2.

Maybe looking at process id's is safer after all. I'm not desperate for
red-hot performance.

Steve
 
I

Ignacio Machin \( .NET/ C# MVP \)

Hi,

Are you releasing the mutex when you close your app? using ReleaseMutex ?

Also, I would guess it implement IDisposable, so you better call Dispose
too.

cheers,
 
S

Steve Barnett

My code runs in the Main() function, before the main form is created, so I
would expect the I didn't need a Dispose() override (I could be totally
wrong - this is a learning exercise).

static class Program
{
/// <summary>
/// The main entry point for the application.
/// </summary>
[STAThread]
static void Main()
{
bool FirstInstance = false;
Mutex AppMutex = new Mutex(true, "IPM_Licence_Editor", out
FirstInstance);

if (FirstInstance == true)
{
Application.EnableVisualStyles();
Application.Run(new MainForm());
}
}
}

Other variant's I've tried include maning the Mutex a static variable and
including an AppMutex.ReleaseMutex() after the Application.Run.

What actually happens is that every tmie I click on my app (after the first
instance), a new instance is created and it appears to hang at the creation
of the Mutex. I can see them listed in TaskManager. When I close the one
"running" copy, I get the AbandonedMutex exception and all instances close.

Steve
 
W

Willy Denoyette [MVP]

A Mutex holds an OS handle and implemnts IDisposable, so you need to Dispose
of the instance, the easiest to do is by means of a using block like
this....

....
using(Mutex AppMutex = new Mutex(true, "IPM_Licence_Editor", out
FirstInstance))
{
if (FirstInstance == true)
{
...

}// end of using block, AppMutex will be disposed and its handle freed.


Willy.


Steve Barnett said:
My code runs in the Main() function, before the main form is created, so I
would expect the I didn't need a Dispose() override (I could be totally
wrong - this is a learning exercise).

static class Program
{
/// <summary>
/// The main entry point for the application.
/// </summary>
[STAThread]
static void Main()
{
bool FirstInstance = false;
Mutex AppMutex = new Mutex(true, "IPM_Licence_Editor", out
FirstInstance);

if (FirstInstance == true)
{
Application.EnableVisualStyles();
Application.Run(new MainForm());
}
}
}

Other variant's I've tried include maning the Mutex a static variable and
including an AppMutex.ReleaseMutex() after the Application.Run.

What actually happens is that every tmie I click on my app (after the
first instance), a new instance is created and it appears to hang at the
creation of the Mutex. I can see them listed in TaskManager. When I close
the one "running" copy, I get the AbandonedMutex exception and all
instances close.

Steve



Ignacio Machin ( .NET/ C# MVP ) said:
Hi,

Are you releasing the mutex when you close your app? using ReleaseMutex ?

Also, I would guess it implement IDisposable, so you better call Dispose
too.

cheers,
 
S

Steve Barnett

Got you. It still doesn't work, but now I understand where you're coming
from. The code I have ended up with is:

static void Main()
{
bool FirstInstance = false;
using (Mutex AppMutex = new Mutex(true, "IPM_Licence_Editor", out
FirstInstance))
{
if (FirstInstance == true)
{
Application.EnableVisualStyles();
Application.Run(new MainForm());
}
} // Mutex will be disposed of here
}

Which should work, I believe. However, I still have the problem that
multiple apps get started and sit there waiting for the first version to
end. When it does, all of the ones queued up fail with the Abandoned Mutex
Exception.

This isn't critical to my app right now, so I guess I'd better come round it
again when I've moved on from the Beta2 libraries.

Thanks, everyone, for the help.
Steve


Willy Denoyette said:
A Mutex holds an OS handle and implemnts IDisposable, so you need to
Dispose of the instance, the easiest to do is by means of a using block
like this....

...
using(Mutex AppMutex = new Mutex(true, "IPM_Licence_Editor", out
FirstInstance))
{
if (FirstInstance == true)
{
...

}// end of using block, AppMutex will be disposed and its handle freed.


Willy.


Steve Barnett said:
My code runs in the Main() function, before the main form is created, so
I would expect the I didn't need a Dispose() override (I could be totally
wrong - this is a learning exercise).

static class Program
{
/// <summary>
/// The main entry point for the application.
/// </summary>
[STAThread]
static void Main()
{
bool FirstInstance = false;
Mutex AppMutex = new Mutex(true, "IPM_Licence_Editor", out
FirstInstance);

if (FirstInstance == true)
{
Application.EnableVisualStyles();
Application.Run(new MainForm());
}
}
}

Other variant's I've tried include maning the Mutex a static variable and
including an AppMutex.ReleaseMutex() after the Application.Run.

What actually happens is that every tmie I click on my app (after the
first instance), a new instance is created and it appears to hang at the
creation of the Mutex. I can see them listed in TaskManager. When I close
the one "running" copy, I get the AbandonedMutex exception and all
instances close.

Steve



Ignacio Machin ( .NET/ C# MVP ) said:
Hi,

Are you releasing the mutex when you close your app? using ReleaseMutex
?

Also, I would guess it implement IDisposable, so you better call Dispose
too.

cheers,

--
Ignacio Machin,
ignacio.machin AT dot.state.fl.us
Florida Department Of Transportation



I've been trying to do this all afternoon. The code looks Ok and I'm
getting a single instance of my app started, but I'm also getting an
"Abandoned Mutex Exception" generated when my app closes. I've had a
look on CodeProject.Com and it appears that this is probably a problem
with the .Net 2.0 Beta 2.

Maybe looking at process id's is safer after all. I'm not desperate for
red-hot performance.

Steve


"Ignacio Machin ( .NET/ C# MVP )" <ignacio.machin AT dot.state.fl.us>
wrote in message Hi,

Use a mutex:

http://www.yoda.arachsys.com/csharp/faq/#one.application.instance


cheers,

--
Ignacio Machin,
ignacio.machin AT dot.state.fl.us
Florida Department Of Transportation



I want to ensure that there is only ever one instance of my app
running on a single PC at any time. I understand that I can achieve
this by using a mutex and, if I can't take ownership of the mutex, I
know there is another instance of my program running.

Problem is, how do I get the "new" instance to communicate with the
"old" instance? The new one will have been started with a command
line parameter that I want to pass to the old instance for execution.
In my VB6 days, I did this using DDE (old, but safe).

What's the C# equivalent?

Can you point me at the classes I might need to work with please (No
detailed code, please - I'm trying to learn this stuff for myself).

Thanks
Steve
 
I

Ignacio Machin \( .NET/ C# MVP \)

Hi,

You have to pass false to the first parameter ( it's correctly in the link
I gave you)

from msdn:
If name is not a null reference (Nothing in Visual Basic) and initiallyOwned
is true, then the application must ensure that a mutex that has the same
name and is owned by the calling thread does not already exist. If the mutex
is being used for cross-process communication, you should set initiallyOwned
to false, or use the Mutex(Boolean, String, Boolean) constructor. Otherwise,
it will be difficult to determine which process has initial ownership.

If you pass true the mutex will wait until it adquire it. This is not what
you want !
You have no use for the mutex, you only needs to know if the mutex exist
(indicating another instance) or not.

new Mutex(false, "Local\\"+someUniqueName, out firstInstance);

is the correct set of parameters.


cheers,

--
Ignacio Machin,
ignacio.machin AT dot.state.fl.us
Florida Department Of Transportation



Steve Barnett said:
Got you. It still doesn't work, but now I understand where you're coming
from. The code I have ended up with is:

static void Main()
{
bool FirstInstance = false;
using (Mutex AppMutex = new Mutex(true, "IPM_Licence_Editor", out
FirstInstance))
{
if (FirstInstance == true)
{
Application.EnableVisualStyles();
Application.Run(new MainForm());
}
} // Mutex will be disposed of here
}

Which should work, I believe. However, I still have the problem that
multiple apps get started and sit there waiting for the first version to
end. When it does, all of the ones queued up fail with the Abandoned Mutex
Exception.

This isn't critical to my app right now, so I guess I'd better come round
it again when I've moved on from the Beta2 libraries.

Thanks, everyone, for the help.
Steve


Willy Denoyette said:
A Mutex holds an OS handle and implemnts IDisposable, so you need to
Dispose of the instance, the easiest to do is by means of a using block
like this....

...
using(Mutex AppMutex = new Mutex(true, "IPM_Licence_Editor", out
FirstInstance))
{
if (FirstInstance == true)
{
...

}// end of using block, AppMutex will be disposed and its handle freed.


Willy.


Steve Barnett said:
My code runs in the Main() function, before the main form is created, so
I would expect the I didn't need a Dispose() override (I could be
totally wrong - this is a learning exercise).

static class Program
{
/// <summary>
/// The main entry point for the application.
/// </summary>
[STAThread]
static void Main()
{
bool FirstInstance = false;
Mutex AppMutex = new Mutex(true, "IPM_Licence_Editor", out
FirstInstance);

if (FirstInstance == true)
{
Application.EnableVisualStyles();
Application.Run(new MainForm());
}
}
}

Other variant's I've tried include maning the Mutex a static variable
and including an AppMutex.ReleaseMutex() after the Application.Run.

What actually happens is that every tmie I click on my app (after the
first instance), a new instance is created and it appears to hang at the
creation of the Mutex. I can see them listed in TaskManager. When I
close the one "running" copy, I get the AbandonedMutex exception and all
instances close.

Steve



"Ignacio Machin ( .NET/ C# MVP )" <ignacio.machin AT dot.state.fl.us>
wrote in message Hi,

Are you releasing the mutex when you close your app? using ReleaseMutex
?

Also, I would guess it implement IDisposable, so you better call
Dispose too.

cheers,

--
Ignacio Machin,
ignacio.machin AT dot.state.fl.us
Florida Department Of Transportation



I've been trying to do this all afternoon. The code looks Ok and I'm
getting a single instance of my app started, but I'm also getting an
"Abandoned Mutex Exception" generated when my app closes. I've had a
look on CodeProject.Com and it appears that this is probably a problem
with the .Net 2.0 Beta 2.

Maybe looking at process id's is safer after all. I'm not desperate
for red-hot performance.

Steve


"Ignacio Machin ( .NET/ C# MVP )" <ignacio.machin AT dot.state.fl.us>
wrote in message Hi,

Use a mutex:

http://www.yoda.arachsys.com/csharp/faq/#one.application.instance


cheers,

--
Ignacio Machin,
ignacio.machin AT dot.state.fl.us
Florida Department Of Transportation



I want to ensure that there is only ever one instance of my app
running on a single PC at any time. I understand that I can achieve
this by using a mutex and, if I can't take ownership of the mutex, I
know there is another instance of my program running.

Problem is, how do I get the "new" instance to communicate with the
"old" instance? The new one will have been started with a command
line parameter that I want to pass to the old instance for
execution. In my VB6 days, I did this using DDE (old, but safe).

What's the C# equivalent?

Can you point me at the classes I might need to work with please (No
detailed code, please - I'm trying to learn this stuff for myself).

Thanks
Steve
 
S

Steve Barnett

Thanks, that's working now. I took the "true" from Willy's post - by then
I'd got so frustrated I wasn't reading the documentation any more.

Well, that's the easy bit over, now I need to make my new instance talk to
the old instance.

Oh joy!

Thanks for all the help.
Steve


Ignacio Machin ( .NET/ C# MVP ) said:
Hi,

You have to pass false to the first parameter ( it's correctly in the link
I gave you)

from msdn:
If name is not a null reference (Nothing in Visual Basic) and
initiallyOwned is true, then the application must ensure that a mutex that
has the same name and is owned by the calling thread does not already
exist. If the mutex is being used for cross-process communication, you
should set initiallyOwned to false, or use the Mutex(Boolean, String,
Boolean) constructor. Otherwise, it will be difficult to determine which
process has initial ownership.

If you pass true the mutex will wait until it adquire it. This is not what
you want !
You have no use for the mutex, you only needs to know if the mutex exist
(indicating another instance) or not.

new Mutex(false, "Local\\"+someUniqueName, out firstInstance);

is the correct set of parameters.


cheers,

--
Ignacio Machin,
ignacio.machin AT dot.state.fl.us
Florida Department Of Transportation



Steve Barnett said:
Got you. It still doesn't work, but now I understand where you're coming
from. The code I have ended up with is:

static void Main()
{
bool FirstInstance = false;
using (Mutex AppMutex = new Mutex(true, "IPM_Licence_Editor", out
FirstInstance))
{
if (FirstInstance == true)
{
Application.EnableVisualStyles();
Application.Run(new MainForm());
}
} // Mutex will be disposed of here
}

Which should work, I believe. However, I still have the problem that
multiple apps get started and sit there waiting for the first version to
end. When it does, all of the ones queued up fail with the Abandoned
Mutex Exception.

This isn't critical to my app right now, so I guess I'd better come round
it again when I've moved on from the Beta2 libraries.

Thanks, everyone, for the help.
Steve


Willy Denoyette said:
A Mutex holds an OS handle and implemnts IDisposable, so you need to
Dispose of the instance, the easiest to do is by means of a using block
like this....

...
using(Mutex AppMutex = new Mutex(true, "IPM_Licence_Editor", out
FirstInstance))
{
if (FirstInstance == true)
{
...

}// end of using block, AppMutex will be disposed and its handle freed.


Willy.


My code runs in the Main() function, before the main form is created,
so I would expect the I didn't need a Dispose() override (I could be
totally wrong - this is a learning exercise).

static class Program
{
/// <summary>
/// The main entry point for the application.
/// </summary>
[STAThread]
static void Main()
{
bool FirstInstance = false;
Mutex AppMutex = new Mutex(true, "IPM_Licence_Editor", out
FirstInstance);

if (FirstInstance == true)
{
Application.EnableVisualStyles();
Application.Run(new MainForm());
}
}
}

Other variant's I've tried include maning the Mutex a static variable
and including an AppMutex.ReleaseMutex() after the Application.Run.

What actually happens is that every tmie I click on my app (after the
first instance), a new instance is created and it appears to hang at
the creation of the Mutex. I can see them listed in TaskManager. When I
close the one "running" copy, I get the AbandonedMutex exception and
all instances close.

Steve



"Ignacio Machin ( .NET/ C# MVP )" <ignacio.machin AT dot.state.fl.us>
wrote in message Hi,

Are you releasing the mutex when you close your app? using
ReleaseMutex ?

Also, I would guess it implement IDisposable, so you better call
Dispose too.

cheers,

--
Ignacio Machin,
ignacio.machin AT dot.state.fl.us
Florida Department Of Transportation



I've been trying to do this all afternoon. The code looks Ok and I'm
getting a single instance of my app started, but I'm also getting an
"Abandoned Mutex Exception" generated when my app closes. I've had a
look on CodeProject.Com and it appears that this is probably a
problem with the .Net 2.0 Beta 2.

Maybe looking at process id's is safer after all. I'm not desperate
for red-hot performance.

Steve


"Ignacio Machin ( .NET/ C# MVP )" <ignacio.machin AT dot.state.fl.us>
wrote in message Hi,

Use a mutex:

http://www.yoda.arachsys.com/csharp/faq/#one.application.instance


cheers,

--
Ignacio Machin,
ignacio.machin AT dot.state.fl.us
Florida Department Of Transportation



I want to ensure that there is only ever one instance of my app
running on a single PC at any time. I understand that I can achieve
this by using a mutex and, if I can't take ownership of the mutex, I
know there is another instance of my program running.

Problem is, how do I get the "new" instance to communicate with the
"old" instance? The new one will have been started with a command
line parameter that I want to pass to the old instance for
execution. In my VB6 days, I did this using DDE (old, but safe).

What's the C# equivalent?

Can you point me at the classes I might need to work with please
(No detailed code, please - I'm trying to learn this stuff for
myself).

Thanks
Steve
 
W

Willy Denoyette [MVP]

Steve Barnett said:
Thanks, that's working now. I took the "true" from Willy's post - by then
Which I took from your's ;-)
.....
and did not pay attention to it, I just wanted to show you the wrapping in a
using block.

Willy.
 
S

Steve Barnett

I paid intense attention to the code you posted... too intense <bg>

It wasn't meant as a criticism of you. I do appreciate the help you and the
others offered.

Steve
 
G

Guest

In good old VB6 one line of code would do:


If App.PrevInstance Then End



Nicholas Paldino said:
Unfortunately, this is a incredibly inefficient way of doing this, and not accurate, either.

If you are using .NET 2.0, derive a class from the WindowsFormsApplicationBase class in the Microsoft.VisualBasic.ApplicationServices namespace (in Microsoft.VisualBasic.dll). There is a protected property in that class named IsSingleInstance. Set it to true in your derived class (in the constructor).

Then, you can call the Run method on your derived class like you would call the Run method on the Application class. It will then run your program.

Additionally, you can sign up for the StartupNextInstance event (or override your OnStartupNextInstance method in your derived class). This is called when another instance of your app is started. The event, however, fires in the instance that is already running. The WindowsFormsApplicationBase takes care of the interprocess communication for you.

If you are not using .NET 2.0, you should use a Mutex with a unique name (I find that the assembly qualified type name is a good unique name) and try and get access to it. If you can not, then you know that another instance of your app is running.

If you want the first app to know the second app was started up (unsuccessfully), then you will have to create an interprocess communication mechanism (such as remoting, which is what WindowsFormsApplicationBase uses, but it uses the new IPC channel, which uses named pipes, which is more efficient than the TCP or HTTP channels) to communicate that information to the original application.

Hope this helps.


--
- Nicholas Paldino [.NET/C# MVP]
- (e-mail address removed)
Hi,

it's quite simple thanks to .net framework which provides everything you need ;-)

using System.Diagnostics;

public static bool IsOneInstance()
{
Process pcur = Process.GetCurrentProcess();
Process[] ps = Process.GetProcesses();
foreach( Process p in ps )
{
if ( pcur.Id != p.Id )
if ( pcur.ProcessName == p.ProcessName )
return false;

}
return true;
}
Jey


Steve Barnett said:
I want to ensure that there is only ever one instance of my app running on a
single PC at any time. I understand that I can achieve this by using a mutex
and, if I can't take ownership of the mutex, I know there is another
instance of my program running.

Problem is, how do I get the "new" instance to communicate with the "old"
instance? The new one will have been started with a command line parameter
that I want to pass to the old instance for execution. In my VB6 days, I did
this using DDE (old, but safe).

What's the C# equivalent?

Can you point me at the classes I might need to work with please (No
detailed code, please - I'm trying to learn this stuff for myself).

Thanks
Steve
 
S

Steve Barnett

I know... and half a dozen lines of DDE code would have transferred my
command line parameter to the running application and I would have achieved
something useful in the last three days. Unfortunately, the world has moved
on (without me, so far) and I'm trying to catch up with the more productive
world of C#.

I now know it ain't gonna be as easy as the hipe promised. Still, if it was
that easy, everyone would be doing it.

Steve



Maruthi said:
In good old VB6 one line of code would do:


If App.PrevInstance Then End



Nicholas Paldino said:
Unfortunately, this is a incredibly inefficient way of doing this,
and not accurate, either.

If you are using .NET 2.0, derive a class from the
WindowsFormsApplicationBase class in the
Microsoft.VisualBasic.ApplicationServices namespace (in
Microsoft.VisualBasic.dll). There is a protected property in that class
named IsSingleInstance. Set it to true in your derived class (in the
constructor).

Then, you can call the Run method on your derived class like you
would call the Run method on the Application class. It will then run
your program.

Additionally, you can sign up for the StartupNextInstance event (or
override your OnStartupNextInstance method in your derived class). This
is called when another instance of your app is started. The event,
however, fires in the instance that is already running. The
WindowsFormsApplicationBase takes care of the interprocess communication
for you.

If you are not using .NET 2.0, you should use a Mutex with a unique
name (I find that the assembly qualified type name is a good unique name)
and try and get access to it. If you can not, then you know that another
instance of your app is running.

If you want the first app to know the second app was started up
(unsuccessfully), then you will have to create an interprocess
communication mechanism (such as remoting, which is what
WindowsFormsApplicationBase uses, but it uses the new IPC channel, which
uses named pipes, which is more efficient than the TCP or HTTP channels)
to communicate that information to the original application.

Hope this helps.


--
- Nicholas Paldino [.NET/C# MVP]
- (e-mail address removed)
Hi,

it's quite simple thanks to .net framework which provides everything
you need ;-)

using System.Diagnostics;

public static bool IsOneInstance()
{
Process pcur = Process.GetCurrentProcess();
Process[] ps = Process.GetProcesses();
foreach( Process p in ps )
{
if ( pcur.Id != p.Id )
if ( pcur.ProcessName == p.ProcessName )
return false;

}
return true;
}
Jey


Steve Barnett said:
I want to ensure that there is only ever one instance of my app running on a
single PC at any time. I understand that I can achieve this by using a mutex
and, if I can't take ownership of the mutex, I know there is another
instance of my program running.

Problem is, how do I get the "new" instance to communicate with the "old"
instance? The new one will have been started with a command line parameter
that I want to pass to the old instance for execution. In my VB6 days, I did
this using DDE (old, but safe).

What's the C# equivalent?

Can you point me at the classes I might need to work with please (No
detailed code, please - I'm trying to learn this stuff for myself).

Thanks
Steve
 

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