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 18 5618
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" <no****@nodomain.com> a écrit dans le message de news: %2****************@TK2MSFTNGP12.phx.gbl... 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
Thank you
Steve
"Jérôme Bonnet" <jb*****@topsys.fr> wrote in message news:43***********************@news.wanadoo.fr...
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" <no****@nodomain.com> a écrit dans le message de news: %2****************@TK2MSFTNGP12.phx.gbl... 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
"Jérôme Bonnet" <jb*****@topsys.fr> skrev i en meddelelse
news:43***********************@news.wanadoo.fr... 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?
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]
- mv*@spam.guard.caspershouse.com
"Jérôme Bonnet" <jb*****@topsys.fr> wrote in message news:43***********************@news.wanadoo.fr...
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" <no****@nodomain.com> a écrit dans le message de news: %2****************@TK2MSFTNGP12.phx.gbl... 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
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
"Nicholas Paldino [.NET/C# MVP]" <mv*@spam.guard.caspershouse.com> wrote in message news:e5**************@TK2MSFTNGP10.phx.gbl...
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]
- mv*@spam.guard.caspershouse.com
"Jérôme Bonnet" <jb*****@topsys.fr> wrote in message news:43***********************@news.wanadoo.fr...
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" <no****@nodomain.com> a écrit dans le message de news: %2****************@TK2MSFTNGP12.phx.gbl... 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
"Peter Kirk" <pk@alpha-solutions.dk> wrote in message
news:e3*************@TK2MSFTNGP15.phx.gbl... "Jérôme Bonnet" <jb*****@topsys.fr> skrev i en meddelelse news:43***********************@news.wanadoo.fr... 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
Hi,
Use a mutex: http://www.yoda.arachsys.com/csharp/...ation.instance
cheers,
--
Ignacio Machin,
ignacio.machin AT dot.state.fl.us
Florida Department Of Transportation
"Steve Barnett" <no****@nodomain.com> wrote in message
news:%2****************@TK2MSFTNGP12.phx.gbl... 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'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 news:%2****************@TK2MSFTNGP09.phx.gbl... Hi,
Use a mutex:
http://www.yoda.arachsys.com/csharp/...ation.instance
cheers,
-- Ignacio Machin, ignacio.machin AT dot.state.fl.us Florida Department Of Transportation "Steve Barnett" <no****@nodomain.com> wrote in message news:%2****************@TK2MSFTNGP12.phx.gbl...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
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
"Steve Barnett" <no****@nodomain.com> wrote in message
news:%2****************@TK2MSFTNGP09.phx.gbl... 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 news:%2****************@TK2MSFTNGP09.phx.gbl... Hi,
Use a mutex:
http://www.yoda.arachsys.com/csharp/...ation.instance
cheers,
-- Ignacio Machin, ignacio.machin AT dot.state.fl.us Florida Department Of Transportation "Steve Barnett" <no****@nodomain.com> wrote in message news:%2****************@TK2MSFTNGP12.phx.gbl...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
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 news:%2****************@TK2MSFTNGP15.phx.gbl... 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 "Steve Barnett" <no****@nodomain.com> wrote in message news:%2****************@TK2MSFTNGP09.phx.gbl... 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 news:%2****************@TK2MSFTNGP09.phx.gbl... Hi,
Use a mutex:
http://www.yoda.arachsys.com/csharp/...ation.instance
cheers,
-- Ignacio Machin, ignacio.machin AT dot.state.fl.us Florida Department Of Transportation "Steve Barnett" <no****@nodomain.com> wrote in message news:%2****************@TK2MSFTNGP12.phx.gbl... 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
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" <no****@nodomain.com> wrote in message
news:OC*************@tk2msftngp13.phx.gbl... 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 news:%2****************@TK2MSFTNGP15.phx.gbl... 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 "Steve Barnett" <no****@nodomain.com> wrote in message news:%2****************@TK2MSFTNGP09.phx.gbl... 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 news:%2****************@TK2MSFTNGP09.phx.gbl... Hi,
Use a mutex:
http://www.yoda.arachsys.com/csharp/...ation.instance
cheers,
-- Ignacio Machin, ignacio.machin AT dot.state.fl.us Florida Department Of Transportation "Steve Barnett" <no****@nodomain.com> wrote in message news:%2****************@TK2MSFTNGP12.phx.gbl... >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 >
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 [MVP]" <wi*************@telenet.be> wrote in message
news:OL**************@TK2MSFTNGP15.phx.gbl... 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" <no****@nodomain.com> wrote in message news:OC*************@tk2msftngp13.phx.gbl... 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 news:%2****************@TK2MSFTNGP15.phx.gbl... 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 "Steve Barnett" <no****@nodomain.com> wrote in message news:%2****************@TK2MSFTNGP09.phx.gbl... 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 news:%2****************@TK2MSFTNGP09.phx.gbl... > Hi, > > Use a mutex: > > http://www.yoda.arachsys.com/csharp/...ation.instance > > > cheers, > > -- > Ignacio Machin, > ignacio.machin AT dot.state.fl.us > Florida Department Of Transportation > > > > "Steve Barnett" <no****@nodomain.com> wrote in message > news:%2****************@TK2MSFTNGP12.phx.gbl... >>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 >> > >
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" <no****@nodomain.com> wrote in message
news:OX**************@TK2MSFTNGP15.phx.gbl... 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 [MVP]" <wi*************@telenet.be> wrote in message news:OL**************@TK2MSFTNGP15.phx.gbl...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" <no****@nodomain.com> wrote in message news:OC*************@tk2msftngp13.phx.gbl... 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 news:%2****************@TK2MSFTNGP15.phx.gbl... 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 "Steve Barnett" <no****@nodomain.com> wrote in message news:%2****************@TK2MSFTNGP09.phx.gbl... > 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 news:%2****************@TK2MSFTNGP09.phx.gbl... >> Hi, >> >> Use a mutex: >> >> http://www.yoda.arachsys.com/csharp/...ation.instance >> >> >> cheers, >> >> -- >> Ignacio Machin, >> ignacio.machin AT dot.state.fl.us >> Florida Department Of Transportation >> >> >> >> "Steve Barnett" <no****@nodomain.com> wrote in message >> news:%2****************@TK2MSFTNGP12.phx.gbl... >>>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 >>> >> >> > >
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 )" <ignacio.machin AT dot.state.fl.us> wrote
in message news:ec**************@TK2MSFTNGP15.phx.gbl... 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" <no****@nodomain.com> wrote in message news:OX**************@TK2MSFTNGP15.phx.gbl... 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 [MVP]" <wi*************@telenet.be> wrote in message news:OL**************@TK2MSFTNGP15.phx.gbl...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" <no****@nodomain.com> wrote in message news:OC*************@tk2msftngp13.phx.gbl... 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 news:%2****************@TK2MSFTNGP15.phx.gbl... > 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 > > > > "Steve Barnett" <no****@nodomain.com> wrote in message > news:%2****************@TK2MSFTNGP09.phx.gbl... >> 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 news:%2****************@TK2MSFTNGP09.phx.gbl... >>> Hi, >>> >>> Use a mutex: >>> >>> http://www.yoda.arachsys.com/csharp/...ation.instance >>> >>> >>> cheers, >>> >>> -- >>> Ignacio Machin, >>> ignacio.machin AT dot.state.fl.us >>> Florida Department Of Transportation >>> >>> >>> >>> "Steve Barnett" <no****@nodomain.com> wrote in message >>> news:%2****************@TK2MSFTNGP12.phx.gbl... >>>>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 >>>> >>> >>> >> >> > >
"Steve Barnett" <no****@nodomain.com> wrote in message
news:uJ**************@TK2MSFTNGP12.phx.gbl... 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.
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
"Willy Denoyette [MVP]" <wi*************@telenet.be> wrote in message
news:%2****************@TK2MSFTNGP10.phx.gbl... "Steve Barnett" <no****@nodomain.com> wrote in message news:uJ**************@TK2MSFTNGP12.phx.gbl... 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.
In good old VB6 one line of code would do:
If App.PrevInstance Then End
"Nicholas Paldino [.NET/C# MVP]" wrote: 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] - mv*@spam.guard.caspershouse.com "Jérôme Bonnet" <jb*****@topsys.fr> wrote in message news:43***********************@news.wanadoo.fr... 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" <no****@nodomain.com> a écrit dans le message de news: %2****************@TK2MSFTNGP12.phx.gbl... >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 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" <Ma*****@discussions.microsoft.com> wrote in message
news:5D**********************************@microsof t.com... In good old VB6 one line of code would do:
If App.PrevInstance Then End "Nicholas Paldino [.NET/C# MVP]" wrote:
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] - mv*@spam.guard.caspershouse.com "Jérôme Bonnet" <jb*****@topsys.fr> wrote in message news:43***********************@news.wanadoo.fr... 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" <no****@nodomain.com> a écrit dans le message de news: %2****************@TK2MSFTNGP12.phx.gbl... >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 > > This thread has been closed and replies have been disabled. Please start a new discussion. Similar topics
by: Elad |
last post by:
Hi,
I have an application that is made up of several executables. I need all
these executables to use the same instance of an object.
What is the best, most efficient way to approach this?
...
|
by: jsale |
last post by:
I have made an ASP.NET web application that connects to SQL Server, reading
and writing data using classes. I was recommended to use session objects to
store the data per user, because each user...
|
by: Maileen |
last post by:
Hi,
How can i do (and test) a single instance of my form ?
thanks,
Maileen
|
by: MrSpock |
last post by:
1. Create a new Windows Application project.
2. Open the project properties and check "Make single instance application".
3. Build.
4. Go to the release folder and run the application.
5. Try to...
|
by: sadanjan |
last post by:
Hi ,
Appreciate if someone can clarify if database Share Memory Limit
(2 GB ) in Unix 32 bit boxes is the top limit for all the databases
put together in a database or is it for each of the...
|
by: Mark Jerde |
last post by:
VS 2005. When I google "CSharp single instance form" the returned pages
usually use a Mutex or the VB.NET runtime library....
|
by: JohnQ |
last post by:
Why would anyone write:
class SomeThing // class littered with non-domain single-instancing code :(
{
private:
SomeThing();
static SomeThing* pInstance_;
public:
static SomeThing*...
|
by: sklett |
last post by:
I suspect the answer might be in one of the words of my subject, but here
goes anyway.
I'm working on a system that will execute a very long (300+) chain of task
objects. Here is some quick...
|
by: Sarath |
last post by:
I've to write a single instance class. there are different methods to
control the single instance of a program. I've tried the following
method
class CSingleton
{
public:
CSingleton&...
|
by: ryjfgjl |
last post by:
ExcelToDatabase: batch import excel into database automatically...
|
by: isladogs |
last post by:
The next Access Europe meeting will be on Wednesday 6 Mar 2024 starting at 18:00 UK time (6PM UTC) and finishing at about 19:15 (7.15PM).
In this month's session, we are pleased to welcome back...
|
by: isladogs |
last post by:
The next Access Europe meeting will be on Wednesday 6 Mar 2024 starting at 18:00 UK time (6PM UTC) and finishing at about 19:15 (7.15PM).
In this month's session, we are pleased to welcome back...
|
by: jfyes |
last post by:
As a hardware engineer, after seeing that CEIWEI recently released a new tool for Modbus RTU Over TCP/UDP filtering and monitoring, I actively went to its official website to take a look. It turned...
|
by: CloudSolutions |
last post by:
Introduction:
For many beginners and individual users, requiring a credit card and email registration may pose a barrier when starting to use cloud servers. However, some cloud server providers now...
|
by: Shællîpôpï 09 |
last post by:
If u are using a keypad phone, how do u turn on JavaScript, to access features like WhatsApp, Facebook, Instagram....
|
by: af34tf |
last post by:
Hi Guys, I have a domain whose name is BytesLimited.com, and I want to sell it. Does anyone know about platforms that allow me to list my domain in auction for free. Thank you
|
by: Faith0G |
last post by:
I am starting a new it consulting business and it's been a while since I setup a new website. Is wordpress still the best web based software for hosting a 5 page website? The webpages will be...
|
by: isladogs |
last post by:
The next Access Europe User Group meeting will be on Wednesday 3 Apr 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM).
In this session, we are pleased to welcome former...
| |