468,133 Members | 1,156 Online
Bytes | Developer Community
New Post

Home Posts Topics Members FAQ

Post your question to a community of 468,133 developers. It's quick & easy.

Only one instance of application

Hi!
I guess this question have been asked a lot of times, but please be tolerant
and if you have any ideas share it.
The question is: how to make availibale only one instance of application and
if second one is loaded it must be
close and give focus to first one.

Thanks for any advice!

Dmitry

P.S.
I've managed to do the following:
static void Main()

{

Process[] appProcess = Process.GetProcessesByName("MyApp");

if(appProcess.Length > 1)

{

MessageBox.Show("Application is already launched!);

return;

}

Application.Run(new FormMainManager());

}
Nov 15 '05 #1
6 4237
"Dmitry Karneyev" <ka******@msn.com> wrote in
news:Oo**************@TK2MSFTNGP09.phx.gbl:
Hi!
I guess this question have been asked a lot of times, but please
be tolerant and if you have any ideas share it.
The question is: how to make availibale only one instance of
application and if second one is loaded it must be
close and give focus to first one.


Dmitry,

http://msdn.microsoft.com/library/de...l=/library/en-
us/dnwinforms/html/reaworapps1.asp

or

http://tinyurl.com/o94q

--
Hope this helps.

Chris.
-------------
C.R. Timmons Consulting, Inc.
http://www.crtimmonsinc.com/
Nov 15 '05 #2
The following code shows how to make sure that there is only one instance of
your Windows Forms application running. The code first searches for
processes with the same name as the and if one is found it makes sure that
was ran from the same location. If it decides that there is another instance
running, it shows that main window of the other instance, otherwise it runs
another instance of the main form.

using System;
using System.Runtime.InteropServices;
using System.Windows.Forms;
using System.Diagnostics;
using System.Reflection;

public class OneInstnace
{
[STAThread]
public static void Main()
{
//Get the running instance.
Process instance = RunningInstance();
if (instance == null)
{
//There isn't another instance, show our form.
Application.Run (new Form());
}
else
{
//There is another instance of this process.
HandleRunningInstance(instance);
}
}
public static Process RunningInstance()
{
Process current = Process.GetCurrentProcess();
Process[] processes = Process.GetProcessesByName (current.ProcessName);

//Loop through the running processes in with the same name
foreach (Process process in processes)
{
//Ignore the current process
if (process.Id != current.Id)
{
//Make sure that the process is running from the exe file.
if (Assembly.GetExecutingAssembly().Location.Replace( "/", "\\") ==
current.MainModule.FileName)
{
//Return the other process instance.
return process;
}
}
}

//No other instance was found, return null.
return null;
}
public static void HandleRunningInstance(Process instance)
{
//Make sure the window is not minimized or maximized
ShowWindowAsync (instance.MainWindowHandle , WS_SHOWNORMAL);

//Set the real intance to foreground window
SetForegroundWindow (instance.MainWindowHandle);
}

[DllImport("User32.dll")]

private static extern bool ShowWindowAsync(
IntPtr hWnd, int cmdShow);
[DllImport("User32.dll")] private static extern bool
SetForegroundWindow(IntPtr hWnd);
private const int WS_SHOWNORMAL = 1;
}
SOURCE:
http://www.c-sharpcorner.com/FAQ/Cre...tanceAppSC.asp

--
Greetz

Jan Tielens
________________________________
Read my weblog: http://weblogs.asp.net/jan
"Dmitry Karneyev" <ka******@msn.com> wrote in message
news:Oo**************@TK2MSFTNGP09.phx.gbl...
Hi!
I guess this question have been asked a lot of times, but please be tolerant and if you have any ideas share it.
The question is: how to make availibale only one instance of application and if second one is loaded it must be
close and give focus to first one.

Thanks for any advice!

Dmitry

P.S.
I've managed to do the following:
static void Main()

{

Process[] appProcess = Process.GetProcessesByName("MyApp");

if(appProcess.Length > 1)

{

MessageBox.Show("Application is already launched!);

return;

}

Application.Run(new FormMainManager());

}

Nov 15 '05 #3
I used the code from that article and had a slight issue with it. (plus the
fact you get a first chance exception in Process.GetProcessesByName())

if the user clicks many times on your exe (with none currently running),
then they all check and find other instances and they all die and your
application does not start.

Had to fix it using a mutex.

Saying that see below for a reply I got the other day (in reply to the first
chance exception issue (I'm running on Win 2000)).

rollasoc,

What platform are you running this on? I think that the implementation
of GetProcessesByName is different depending on the platform (not that you
should ever know or care about it though).

However, for what you are doing, there is an easier way. I would create
a named Mutex instance, and then see if you can get a lock on it. If you
can, then you know your application is not running. If you can't get a
lock, then don't run the app. Basically, place an if block around the call
to the static Run method on the Application class, only entering if you can
obtain the Mutex.

Hope this helps.
--
- Nicholas Paldino [.NET/C# MVP]
- mv*@spam.guard.caspershouse.com


"Jan Tielens" <ja*@no.spam.please.leadit.be> wrote in message
news:#9**************@TK2MSFTNGP11.phx.gbl...
The following code shows how to make sure that there is only one instance of your Windows Forms application running. The code first searches for
processes with the same name as the and if one is found it makes sure that
was ran from the same location. If it decides that there is another instance running, it shows that main window of the other instance, otherwise it runs another instance of the main form.

using System;
using System.Runtime.InteropServices;
using System.Windows.Forms;
using System.Diagnostics;
using System.Reflection;

public class OneInstnace
{
[STAThread]
public static void Main()
{
//Get the running instance.
Process instance = RunningInstance();
if (instance == null)
{
//There isn't another instance, show our form.
Application.Run (new Form());
}
else
{
//There is another instance of this process.
HandleRunningInstance(instance);
}
}
public static Process RunningInstance()
{
Process current = Process.GetCurrentProcess();
Process[] processes = Process.GetProcessesByName (current.ProcessName);

//Loop through the running processes in with the same name
foreach (Process process in processes)
{
//Ignore the current process
if (process.Id != current.Id)
{
//Make sure that the process is running from the exe file.
if (Assembly.GetExecutingAssembly().Location.Replace( "/", "\\") ==
current.MainModule.FileName)
{
//Return the other process instance.
return process;
}
}
}

//No other instance was found, return null.
return null;
}
public static void HandleRunningInstance(Process instance)
{
//Make sure the window is not minimized or maximized
ShowWindowAsync (instance.MainWindowHandle , WS_SHOWNORMAL);

//Set the real intance to foreground window
SetForegroundWindow (instance.MainWindowHandle);
}

[DllImport("User32.dll")]

private static extern bool ShowWindowAsync(
IntPtr hWnd, int cmdShow);
[DllImport("User32.dll")] private static extern bool
SetForegroundWindow(IntPtr hWnd);
private const int WS_SHOWNORMAL = 1;
}
SOURCE:
http://www.c-sharpcorner.com/FAQ/Cre...tanceAppSC.asp

--
Greetz

Jan Tielens
________________________________
Read my weblog: http://weblogs.asp.net/jan
"Dmitry Karneyev" <ka******@msn.com> wrote in message
news:Oo**************@TK2MSFTNGP09.phx.gbl...
Hi!
I guess this question have been asked a lot of times, but please be

tolerant
and if you have any ideas share it.
The question is: how to make availibale only one instance of application

and
if second one is loaded it must be
close and give focus to first one.

Thanks for any advice!

Dmitry

P.S.
I've managed to do the following:
static void Main()

{

Process[] appProcess = Process.GetProcessesByName("MyApp");

if(appProcess.Length > 1)

{

MessageBox.Show("Application is already launched!);

return;

}

Application.Run(new FormMainManager());

}


Nov 15 '05 #4
Great info, thx!

--
Greetz

Jan Tielens
________________________________
Read my weblog: http://weblogs.asp.net/jan
"rollasoc" <ho*****@hotmail.com> wrote in message
news:#U**************@TK2MSFTNGP12.phx.gbl...
I used the code from that article and had a slight issue with it. (plus the fact you get a first chance exception in Process.GetProcessesByName())

if the user clicks many times on your exe (with none currently running),
then they all check and find other instances and they all die and your
application does not start.

Had to fix it using a mutex.

Saying that see below for a reply I got the other day (in reply to the first chance exception issue (I'm running on Win 2000)).

rollasoc,

What platform are you running this on? I think that the implementation of GetProcessesByName is different depending on the platform (not that you
should ever know or care about it though).

However, for what you are doing, there is an easier way. I would create a named Mutex instance, and then see if you can get a lock on it. If you
can, then you know your application is not running. If you can't get a
lock, then don't run the app. Basically, place an if block around the call to the static Run method on the Application class, only entering if you can obtain the Mutex.

Hope this helps.
--
- Nicholas Paldino [.NET/C# MVP]
- mv*@spam.guard.caspershouse.com


"Jan Tielens" <ja*@no.spam.please.leadit.be> wrote in message
news:#9**************@TK2MSFTNGP11.phx.gbl...
The following code shows how to make sure that there is only one instance
of
your Windows Forms application running. The code first searches for
processes with the same name as the and if one is found it makes sure

that was ran from the same location. If it decides that there is another

instance
running, it shows that main window of the other instance, otherwise it

runs
another instance of the main form.

using System;
using System.Runtime.InteropServices;
using System.Windows.Forms;
using System.Diagnostics;
using System.Reflection;

public class OneInstnace
{
[STAThread]
public static void Main()
{
//Get the running instance.
Process instance = RunningInstance();
if (instance == null)
{
//There isn't another instance, show our form.
Application.Run (new Form());
}
else
{
//There is another instance of this process.
HandleRunningInstance(instance);
}
}
public static Process RunningInstance()
{
Process current = Process.GetCurrentProcess();
Process[] processes = Process.GetProcessesByName (current.ProcessName);

//Loop through the running processes in with the same name
foreach (Process process in processes)
{
//Ignore the current process
if (process.Id != current.Id)
{
//Make sure that the process is running from the exe file.
if (Assembly.GetExecutingAssembly().Location.Replace( "/", "\\") ==
current.MainModule.FileName)
{
//Return the other process instance.
return process;
}
}
}

//No other instance was found, return null.
return null;
}
public static void HandleRunningInstance(Process instance)
{
//Make sure the window is not minimized or maximized
ShowWindowAsync (instance.MainWindowHandle , WS_SHOWNORMAL);

//Set the real intance to foreground window
SetForegroundWindow (instance.MainWindowHandle);
}

[DllImport("User32.dll")]

private static extern bool ShowWindowAsync(
IntPtr hWnd, int cmdShow);
[DllImport("User32.dll")] private static extern bool
SetForegroundWindow(IntPtr hWnd);
private const int WS_SHOWNORMAL = 1;
}
SOURCE:
http://www.c-sharpcorner.com/FAQ/Cre...tanceAppSC.asp

--
Greetz

Jan Tielens
________________________________
Read my weblog: http://weblogs.asp.net/jan
"Dmitry Karneyev" <ka******@msn.com> wrote in message
news:Oo**************@TK2MSFTNGP09.phx.gbl...
Hi!
I guess this question have been asked a lot of times, but please be

tolerant
and if you have any ideas share it.
The question is: how to make availibale only one instance of
application and
if second one is loaded it must be
close and give focus to first one.

Thanks for any advice!

Dmitry

P.S.
I've managed to do the following:
static void Main()

{

Process[] appProcess = Process.GetProcessesByName("MyApp");

if(appProcess.Length > 1)

{

MessageBox.Show("Application is already launched!);

return;

}

Application.Run(new FormMainManager());

}



Nov 15 '05 #5
Another one.
http://www.codeproject.com/csharp/singleinstance.asp

P.S. All code I've found uses user32.dll to bring main window of app to
front.
Is it possible to do the same thing using framework?

Dmitry
Nov 15 '05 #6

"Dmitry Karneyev" <ka******@msn.com> wrote in message
news:#Z**************@tk2msftngp13.phx.gbl...
Another one.
http://www.codeproject.com/csharp/singleinstance.asp

P.S. All code I've found uses user32.dll to bring main window of app to
front.
Is it possible to do the same thing using framework?

Dmitry


Dmitry

I've seen nothing in the framework "yet" that will bring the window in
another process to the foreground. That will certainly change in coming
release versions!

One would have to also consider the case of the original instance being in a
minimized state, not just hidden by another window.

The case in the work you cited has one minor problem - if the program is
executed from two different locations, both copies will run - the most
obvious case is a Release version and a Debug version (the cited work sees
that as two distinct executions).

Additionally, the use of the Mutex is exactly the right way to do it, but
the WaitOne is an unnecessary step, and there is no need to establish the
mutex as a static variable, the only requirement is that the life of the
mutex object be exactly that of the object it is trying to protect. The
mutex is a kernel object, so if the name is unique, then subsequent attempts
to create it will be seen in the Mutex(bool, string, bool) constructor (that
third param return true if this call is the first for the named object).

Here is a quick hack (no error checking, no comments, etc...) that I did
some time ago (my apologies, it is in MC++, but the xlate to C# should be
straightforward). Most of the work is done inline in the derived Form
object constructor - and it throws an exception if a multiple instance
condition is discovered. You can use the guidgen utilitiy to create the
seed for a unique name for each appliction. Then wrap the creation of the
main app form in WinMain in an exception handler, and exit without running
the form...

What you do when the second instance is discovered is very much up to you
and the requirments levied thereon. The message box that announces the
discovery of the first instance was included for demo purposes only (one
would likely remove that from a production release). I was playing with
someother things when I did this one - so I stuffed the HWND of the form
into the registry upon first successful invocation. Enumerating the windows
to find the initial instance did not seem to appealing to me at the time. In
the duplicate instance handler, I retreive the stored HWND value from the
registry, and then do a ShowWindow to bring the original form out of a
(potentially) minimized state. Next I pinned the original instance to TOP -
placing it above all other windows in the z-order, notwithstanding any that
have TOPMOST status. Be careful to not use TOPMOST, because that will force
the original window to the highest position in the z-order at that time. To
do this is almost never a user-friendly approach..

regards
roy fine
/* ******************* */
namespace SysWin32{
[DllImport("user32.dll", EntryPoint = "MessageBox", CharSet = Unicode)]
int MessageBox(IntPtr hWnd, wchar_t* lpText, wchar_t* lpCaption, unsigned
int uType);
[DllImport("user32.dll", EntryPoint = "ShowWindow", CharSet = Unicode)]
int ShowWindow(IntPtr hWnd, unsigned int uType);
[DllImport("user32.dll", EntryPoint = "SetWindowPos", CharSet = Unicode)]
int SetWindowPos(IntPtr, IntPtr,int x, int y, int sx, int sy, unsigned int
flags );
}
/* ******************* */
int APIENTRY _tWinMain(HINSTANCE hInstance,HINSTANCE,LPTSTR,int ){
Thread *curThread = System::Threading::Thread::CurrentThread;
curThread->set_Name(S"UNIQUE_THREAD_3A2B4DE1_8F68_4647_9E84_ 5FD4B126696A");
curThread->set_ApartmentState(System::Threading::ApartmentSt ate::STA);
Form1 *frm = 0;
try{
frm = new Form1();
String __gc *regKeyName = S"Software\\RLFine_Testing\\MC_Singleton";
RegistryKey __gc *regKey =
Registry::CurrentUser->CreateSubKey(regKeyName);
String __gc *iVal = frm->get_Handle().ToString();
regKey->SetValue(S"AppHWND",iVal);
regKey->Close();
regKey = NULL;
Application::Run(frm);
}
catch(int /* a */){
frm = NULL;
}
return 0;
}

/* ******************* */
public __gc class Form1 : public System::Windows::Forms::Form{
private:
Mutex *mtxInstance;
....
public:
Form1(void) {
InitializeComponent();
String *tstr = S"UNIQUE_INSTANCE_DF26B334_08A0_4ae5_9260_BBD975FB 6E9E";
mtxInstance = new Mutex(true,tstr,&blMutexOwner);
if(!blMutexOwner) {
SysWin32::MessageBox( 0, L"YIKES!\nhere is already an instance of this
app running!",
L"Multiple Instance Monitor", MB_OK|MB_ICONWARNING);
RegistryKey *regKey =
Registry::CurrentUser->CreateSubKey(S"Software\\RLFine_Testing\\MC_Singl eton
");
Object *obj = regKey->GetValue(S"AppHWND");
String *tstr = obj->ToString();
IntPtr hwnd = IntPtr(System::Convert::ToInt64(tstr));
SysWin32::ShowWindow(hwnd,SW_RESTORE);
SysWin32::SetWindowPos(hwnd,HWND_TOP,0,0,0,0,SWP_N OMOVE|SWP_NOSIZE);
regKey->Close();
regKey = NULL;
throw 1;
}
}
Nov 15 '05 #7

This discussion thread is closed

Replies have been disabled for this discussion.

Similar topics

8 posts views Thread by Li Pang | last post: by
8 posts views Thread by Jon Weston | last post: by
6 posts views Thread by perera | last post: by
20 posts views Thread by Boki Digtal | last post: by
2 posts views Thread by Jassim Rahma | last post: by
By using this site, you agree to our Privacy Policy and Terms of Use.