App "Already Running" Scenario

G

Guest

How, in .NET Windows Forms applications, can I create an app where, if the
user double-clicks or otherwise attempts to start the EXE when it's already
running, it simply brings the already-running application to the front
(standard Windows UI approach). I have figured out how to use the Process
object to find out if this application is already running and I can get va
reference to the already-running Process. But how do I make that Process's
application window/windows come to the front, etc.? And if it can't be done
because of inter-application security restrctions or some-such, how does
Microsoft do it?

Thanks for your help!

Alex
 
G

Guest

use this


static void Main()
{
if ( !CheckProcess() )
{
Application.Run(new App());
}
else
{

MessageBox.Show("Application already running");
Application.Exit();
}
}

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


Bye.


Thomas LEBRUN
 
S

Sijin Joseph

Give this a shot,

Once you get the Process associated with your application

Control mainWindow = Control.FromHandle(myProcess.MainWindowHandle);

//Then try either
mainWindow.BringToFront();
//Or
mainWindow.Focus();
//Or
mainWindow.Show();
 
G

Guest

Hi. You know what? I think I liad before when I said I already had a
reference to the running Process. It's starnge, I'm getting back an array of
Processes from my
".Process.GetProcessesByName()" call and I'm using the array length to
determine whether the application is already running. Length = 1, this is the
first one running. Length > 1, it's already running. Now here's where I go
wrong: If I do:

"AlreadyRunningProcess = ProcessArr[0];" where ProcessArr[] was already
filled from my call to ".Process.GetProcessesByName()", what I get back
doesn't seem to work right. If I then try even the simplest
"AlreadyRunningProcess.MachineName" or anything else, I get null values back.

I've also tried using "AlreadyRunningProcess = ProcessArr[1];" thinking that
maybe the order of process returned would be backward but NEITHER of these
works.

Can you help further?

Thanks!
 
S

Sijin Joseph

Ok here's a thought, when you run the second instance of your application
isn't that also going to have the same process name and get enumerated in
the call to GetProcessByName() so actually you should be checking that
Length > 2, try it. Now you need to correctly identify the already running
process from your current process. That can be done by comparing the process
handles of your current process and the list returned by the
GetProcessByName() method(). Can you also post some sample code if you still
have problems.

--
Sijin Joseph
http://www.indiangeek.net
http://weblogs.asp.net/sjoseph


Alex Maghen said:
Hi. You know what? I think I liad before when I said I already had a
reference to the running Process. It's starnge, I'm getting back an array of
Processes from my
".Process.GetProcessesByName()" call and I'm using the array length to
determine whether the application is already running. Length = 1, this is the
first one running. Length > 1, it's already running. Now here's where I go
wrong: If I do:

"AlreadyRunningProcess = ProcessArr[0];" where ProcessArr[] was already
filled from my call to ".Process.GetProcessesByName()", what I get back
doesn't seem to work right. If I then try even the simplest
"AlreadyRunningProcess.MachineName" or anything else, I get null values back.

I've also tried using "AlreadyRunningProcess = ProcessArr[1];" thinking that
maybe the order of process returned would be backward but NEITHER of these
works.

Can you help further?

Thanks!

Sijin Joseph said:
Give this a shot,

Once you get the Process associated with your application

Control mainWindow = Control.FromHandle(myProcess.MainWindowHandle);

//Then try either
mainWindow.BringToFront();
//Or
mainWindow.Focus();
//Or
mainWindow.Show();
 
G

Guest

Hi. Okay well, I still can't seem to solve this problem. I really appreciate
your help. Here's my entire Main(). It's very short. Can you help me figure
out what I'm doing wrong? THANKS! ...


[STAThread]
static void Main()
{
Process[] ProcessArr =
System.Diagnostics.Process.GetProcessesByName(
System.Diagnostics.Process.GetCurrentProcess().ProcessName
);
Process AlreadyRunningProcess;

//Will never be GREATER THAN 2 by this logic...
// 1 process was the original...
// Process 2 is the one just starting now
if(ProcessArr.Length > 1)
{
//I've tried both [0] AND [1] below
AlreadyRunningProcess = ProcessArr[0];
Control AlreadyRunningMainWind =
Control.FromHandle(AlreadyRunningProcess.MainWindowHandle);

// For text purposes, I've done the next 2 lines.
// Returns NULL string...
string tmpStr = AlreadyRunningProcess.ProcessName;
MessageBox.Show("ProcessName = " + tmpStr);

// AlreadyRunningMainWind is always NULL for some reason!
if(AlreadyRunningMainWind == null)
MessageBox.Show("Window Handle is NULL!");
else
AlreadyRunningMainWind.Focus();
}
else
{
Application.Run(new RunOnlyOnceTestFrm());
}
}


Sijin Joseph said:
Ok here's a thought, when you run the second instance of your application
isn't that also going to have the same process name and get enumerated in
the call to GetProcessByName() so actually you should be checking that
Length > 2, try it. Now you need to correctly identify the already running
process from your current process. That can be done by comparing the process
handles of your current process and the list returned by the
GetProcessByName() method(). Can you also post some sample code if you still
have problems.

--
Sijin Joseph
http://www.indiangeek.net
http://weblogs.asp.net/sjoseph


Alex Maghen said:
Hi. You know what? I think I liad before when I said I already had a
reference to the running Process. It's starnge, I'm getting back an array of
Processes from my
".Process.GetProcessesByName()" call and I'm using the array length to
determine whether the application is already running. Length = 1, this is the
first one running. Length > 1, it's already running. Now here's where I go
wrong: If I do:

"AlreadyRunningProcess = ProcessArr[0];" where ProcessArr[] was already
filled from my call to ".Process.GetProcessesByName()", what I get back
doesn't seem to work right. If I then try even the simplest
"AlreadyRunningProcess.MachineName" or anything else, I get null values back.

I've also tried using "AlreadyRunningProcess = ProcessArr[1];" thinking that
maybe the order of process returned would be backward but NEITHER of these
works.

Can you help further?

Thanks!

Sijin Joseph said:
Give this a shot,

Once you get the Process associated with your application

Control mainWindow = Control.FromHandle(myProcess.MainWindowHandle);

//Then try either
mainWindow.BringToFront();
//Or
mainWindow.Focus();
//Or
mainWindow.Show();

--
Sijin Joseph
http://www.indiangeek.net
http://weblogs.asp.net/sjoseph


How, in .NET Windows Forms applications, can I create an app where, if the
user double-clicks or otherwise attempts to start the EXE when it's
already
running, it simply brings the already-running application to the front
(standard Windows UI approach). I have figured out how to use the Process
object to find out if this application is already running and I can get va
reference to the already-running Process. But how do I make that Process's
application window/windows come to the front, etc.? And if it can't be
done
because of inter-application security restrctions or some-such, how does
Microsoft do it?

Thanks for your help!

Alex
 
G

Guest

ALSO, I'VE DONE A LITTLE MORE DEBUGGING AND WHAT SEEMS TO BE HAPPENING IS
THAT MY "AlreadyRunningProcess.MainWindowHandle" IS, FOR SOME REASON, 0 -
WHICH IS STRANGE BECAUSE "AlreadyRunningProcess.ProcessName" IS COMING BACK
WITH THE RIGHT PROCESS NAME. IF THERE SOMETHING WRONG WITH MY USE OF
Process.MainWindowHandle IN THIS CONTEXT?


Alex Maghen said:
Hi. Okay well, I still can't seem to solve this problem. I really appreciate
your help. Here's my entire Main(). It's very short. Can you help me figure
out what I'm doing wrong? THANKS! ...


[STAThread]
static void Main()
{
Process[] ProcessArr =
System.Diagnostics.Process.GetProcessesByName(
System.Diagnostics.Process.GetCurrentProcess().ProcessName
);
Process AlreadyRunningProcess;

//Will never be GREATER THAN 2 by this logic...
// 1 process was the original...
// Process 2 is the one just starting now
if(ProcessArr.Length > 1)
{
//I've tried both [0] AND [1] below
AlreadyRunningProcess = ProcessArr[0];
Control AlreadyRunningMainWind =
Control.FromHandle(AlreadyRunningProcess.MainWindowHandle);

// For text purposes, I've done the next 2 lines.
// Returns NULL string...
string tmpStr = AlreadyRunningProcess.ProcessName;
MessageBox.Show("ProcessName = " + tmpStr);

// AlreadyRunningMainWind is always NULL for some reason!
if(AlreadyRunningMainWind == null)
MessageBox.Show("Window Handle is NULL!");
else
AlreadyRunningMainWind.Focus();
}
else
{
Application.Run(new RunOnlyOnceTestFrm());
}
}


Sijin Joseph said:
Ok here's a thought, when you run the second instance of your application
isn't that also going to have the same process name and get enumerated in
the call to GetProcessByName() so actually you should be checking that
Length > 2, try it. Now you need to correctly identify the already running
process from your current process. That can be done by comparing the process
handles of your current process and the list returned by the
GetProcessByName() method(). Can you also post some sample code if you still
have problems.

--
Sijin Joseph
http://www.indiangeek.net
http://weblogs.asp.net/sjoseph


Alex Maghen said:
Hi. You know what? I think I liad before when I said I already had a
reference to the running Process. It's starnge, I'm getting back an array of
Processes from my
".Process.GetProcessesByName()" call and I'm using the array length to
determine whether the application is already running. Length = 1, this is the
first one running. Length > 1, it's already running. Now here's where I go
wrong: If I do:

"AlreadyRunningProcess = ProcessArr[0];" where ProcessArr[] was already
filled from my call to ".Process.GetProcessesByName()", what I get back
doesn't seem to work right. If I then try even the simplest
"AlreadyRunningProcess.MachineName" or anything else, I get null values back.

I've also tried using "AlreadyRunningProcess = ProcessArr[1];" thinking that
maybe the order of process returned would be backward but NEITHER of these
works.

Can you help further?

Thanks!

:

Give this a shot,

Once you get the Process associated with your application

Control mainWindow = Control.FromHandle(myProcess.MainWindowHandle);

//Then try either
mainWindow.BringToFront();
//Or
mainWindow.Focus();
//Or
mainWindow.Show();

--
Sijin Joseph
http://www.indiangeek.net
http://weblogs.asp.net/sjoseph


How, in .NET Windows Forms applications, can I create an app where, if the
user double-clicks or otherwise attempts to start the EXE when it's
already
running, it simply brings the already-running application to the front
(standard Windows UI approach). I have figured out how to use the Process
object to find out if this application is already running and I can get va
reference to the already-running Process. But how do I make that Process's
application window/windows come to the front, etc.? And if it can't be
done
because of inter-application security restrctions or some-such, how does
Microsoft do it?

Thanks for your help!

Alex
 
G

Guest

SOORY, BUT I WANT YOU TO KNOW WHAT I'M VERY SLOWLY FIGURING OUT: NOW I'M
LEARNING THAT IF I START THE FIRST PROCESS (WHICH HAS A WINDOW AND ALL) AND
THEN WAIT A MINUTE AND START THE OTHER ONE, THE SECOND ONE FINDS THAT THE
"AlreadyRunningProcess.MainWindowHandle" IS ZERO. *BUT*, IF I START THE FIRST
ONE AND THEN INTERACT WITH IT BY CLICKING A BUTTON IN ITS WINDOW OR
SOMETHING, THEN THE SECOND ONE GETS A PROPER NUMBER FOR
"AlreadyRunningProcess.MainWindowHandle". WHAT'S THAT ABOUT?

STILL, WHEN I THEN USE
"Control AlreadyRunningMainWind =
Control.FromHandle(AlreadyRunningMainWindowHandle);"

AlreadyRunningMainWind STILL COMES OUT AS ZERO IN ANY CASE.



Alex Maghen said:
Hi. Okay well, I still can't seem to solve this problem. I really appreciate
your help. Here's my entire Main(). It's very short. Can you help me figure
out what I'm doing wrong? THANKS! ...


[STAThread]
static void Main()
{
Process[] ProcessArr =
System.Diagnostics.Process.GetProcessesByName(
System.Diagnostics.Process.GetCurrentProcess().ProcessName
);
Process AlreadyRunningProcess;

//Will never be GREATER THAN 2 by this logic...
// 1 process was the original...
// Process 2 is the one just starting now
if(ProcessArr.Length > 1)
{
//I've tried both [0] AND [1] below
AlreadyRunningProcess = ProcessArr[0];
Control AlreadyRunningMainWind =
Control.FromHandle(AlreadyRunningProcess.MainWindowHandle);

// For text purposes, I've done the next 2 lines.
// Returns NULL string...
string tmpStr = AlreadyRunningProcess.ProcessName;
MessageBox.Show("ProcessName = " + tmpStr);

// AlreadyRunningMainWind is always NULL for some reason!
if(AlreadyRunningMainWind == null)
MessageBox.Show("Window Handle is NULL!");
else
AlreadyRunningMainWind.Focus();
}
else
{
Application.Run(new RunOnlyOnceTestFrm());
}
}


Sijin Joseph said:
Ok here's a thought, when you run the second instance of your application
isn't that also going to have the same process name and get enumerated in
the call to GetProcessByName() so actually you should be checking that
Length > 2, try it. Now you need to correctly identify the already running
process from your current process. That can be done by comparing the process
handles of your current process and the list returned by the
GetProcessByName() method(). Can you also post some sample code if you still
have problems.

--
Sijin Joseph
http://www.indiangeek.net
http://weblogs.asp.net/sjoseph


Alex Maghen said:
Hi. You know what? I think I liad before when I said I already had a
reference to the running Process. It's starnge, I'm getting back an array of
Processes from my
".Process.GetProcessesByName()" call and I'm using the array length to
determine whether the application is already running. Length = 1, this is the
first one running. Length > 1, it's already running. Now here's where I go
wrong: If I do:

"AlreadyRunningProcess = ProcessArr[0];" where ProcessArr[] was already
filled from my call to ".Process.GetProcessesByName()", what I get back
doesn't seem to work right. If I then try even the simplest
"AlreadyRunningProcess.MachineName" or anything else, I get null values back.

I've also tried using "AlreadyRunningProcess = ProcessArr[1];" thinking that
maybe the order of process returned would be backward but NEITHER of these
works.

Can you help further?

Thanks!

:

Give this a shot,

Once you get the Process associated with your application

Control mainWindow = Control.FromHandle(myProcess.MainWindowHandle);

//Then try either
mainWindow.BringToFront();
//Or
mainWindow.Focus();
//Or
mainWindow.Show();

--
Sijin Joseph
http://www.indiangeek.net
http://weblogs.asp.net/sjoseph


How, in .NET Windows Forms applications, can I create an app where, if the
user double-clicks or otherwise attempts to start the EXE when it's
already
running, it simply brings the already-running application to the front
(standard Windows UI approach). I have figured out how to use the Process
object to find out if this application is already running and I can get va
reference to the already-running Process. But how do I make that Process's
application window/windows come to the front, etc.? And if it can't be
done
because of inter-application security restrctions or some-such, how does
Microsoft do it?

Thanks for your help!

Alex
 
E

Etienne Boucher

You could use a mutex to make sure you only have one running process at a
time and remoting to share the command line arguments. I found something
like this somewhere online.

public class MainClass
{
private MainClass()
{
}
/// <summary>
/// Create a new window. This should be invoked on the UI thread.
/// </summary>
static void Main(string[] args)
{
// Mutex used to lock while one instance is running.
Mutex mutex = null;
try
{
mutex = new Mutex(false, Application.ProductName);
if (mutex.WaitOne(TimeSpan.Zero, false))
{
// TODO: Setup remoting server
// TODO: Create Window
System.Windows.Forms.Application.Run();
}
else
{
// Null the mutex, since it's owned by another instance
mutex = null;
// TODO: Remoting client
}
}
catch (Exception)
{
}
finally
{
// If we are the singleton object
if (null != mutex)
{
mutex.ReleaseMutex();
mutex.Close();
mutex = null;
}
}
}
}
 
S

Sijin Joseph

Hi Alex,

My mistake, i forgot that Control.FromHandle() only works on handles
belonging to the current process as "Windows" maintains a window table on a
per process basis. So in order to bring your other window to the front you
will have to use some form of Inter Process Communication like windows
messages to communicate to your other instance. I found this article that
uses P/Invoke to bring the previous instance window to the foreground ,
check it out,
http://www.devhood.com/tutorials/tutorial_details.aspx?tutorial_id=711

--
Sijin Joseph
http://www.indiangeek.net
http://weblogs.asp.net/sjoseph


Alex Maghen said:
Hi. Okay well, I still can't seem to solve this problem. I really appreciate
your help. Here's my entire Main(). It's very short. Can you help me figure
out what I'm doing wrong? THANKS! ...


[STAThread]
static void Main()
{
Process[] ProcessArr =
System.Diagnostics.Process.GetProcessesByName(
System.Diagnostics.Process.GetCurrentProcess().ProcessName
);
Process AlreadyRunningProcess;

//Will never be GREATER THAN 2 by this logic...
// 1 process was the original...
// Process 2 is the one just starting now
if(ProcessArr.Length > 1)
{
//I've tried both [0] AND [1] below
AlreadyRunningProcess = ProcessArr[0];
Control AlreadyRunningMainWind =
Control.FromHandle(AlreadyRunningProcess.MainWindowHandle);

// For text purposes, I've done the next 2 lines.
// Returns NULL string...
string tmpStr = AlreadyRunningProcess.ProcessName;
MessageBox.Show("ProcessName = " + tmpStr);

// AlreadyRunningMainWind is always NULL for some reason!
if(AlreadyRunningMainWind == null)
MessageBox.Show("Window Handle is NULL!");
else
AlreadyRunningMainWind.Focus();
}
else
{
Application.Run(new RunOnlyOnceTestFrm());
}
}


Sijin Joseph said:
Ok here's a thought, when you run the second instance of your application
isn't that also going to have the same process name and get enumerated in
the call to GetProcessByName() so actually you should be checking that
Length > 2, try it. Now you need to correctly identify the already running
process from your current process. That can be done by comparing the process
handles of your current process and the list returned by the
GetProcessByName() method(). Can you also post some sample code if you still
have problems.

--
Sijin Joseph
http://www.indiangeek.net
http://weblogs.asp.net/sjoseph


Alex Maghen said:
Hi. You know what? I think I liad before when I said I already had a
reference to the running Process. It's starnge, I'm getting back an
array
of
Processes from my
".Process.GetProcessesByName()" call and I'm using the array length to
determine whether the application is already running. Length = 1, this
is
the
first one running. Length > 1, it's already running. Now here's where I go
wrong: If I do:

"AlreadyRunningProcess = ProcessArr[0];" where ProcessArr[] was already
filled from my call to ".Process.GetProcessesByName()", what I get back
doesn't seem to work right. If I then try even the simplest
"AlreadyRunningProcess.MachineName" or anything else, I get null
values
back.
I've also tried using "AlreadyRunningProcess = ProcessArr[1];"
thinking
that
maybe the order of process returned would be backward but NEITHER of these
works.

Can you help further?

Thanks!

:

Give this a shot,

Once you get the Process associated with your application

Control mainWindow = Control.FromHandle(myProcess.MainWindowHandle);

//Then try either
mainWindow.BringToFront();
//Or
mainWindow.Focus();
//Or
mainWindow.Show();

--
Sijin Joseph
http://www.indiangeek.net
http://weblogs.asp.net/sjoseph


How, in .NET Windows Forms applications, can I create an app
where, if
the
user double-clicks or otherwise attempts to start the EXE when it's
already
running, it simply brings the already-running application to the front
(standard Windows UI approach). I have figured out how to use the Process
object to find out if this application is already running and I
can
get va
reference to the already-running Process. But how do I make that Process's
application window/windows come to the front, etc.? And if it can't be
done
because of inter-application security restrctions or some-such,
how
does
Microsoft do it?

Thanks for your help!

Alex
 
G

Guest

Oh thank you thank you thank you! Finally, something that works... Now I have
only one little question about this approach and if you can help me with
this, I promise I'll leave you alone (for a little while):

In order for this approach to work, it seems that the application must KNOW
the caption of the main window because it seems it's the only way that it can
use Win32 stuff to FIND the appropriate window to bring to the front. My
problem is, what if I want the caption of the main window to be changeable.
Is there any other value that can be used - maybe something which isn't
displayed to the user but can still be acquired in Win32 in code?

Any ideas would be MUCH appreciated.

Alex

Sijin Joseph said:
Hi Alex,

My mistake, i forgot that Control.FromHandle() only works on handles
belonging to the current process as "Windows" maintains a window table on a
per process basis. So in order to bring your other window to the front you
will have to use some form of Inter Process Communication like windows
messages to communicate to your other instance. I found this article that
uses P/Invoke to bring the previous instance window to the foreground ,
check it out,
http://www.devhood.com/tutorials/tutorial_details.aspx?tutorial_id=711

--
Sijin Joseph
http://www.indiangeek.net
http://weblogs.asp.net/sjoseph


Alex Maghen said:
Hi. Okay well, I still can't seem to solve this problem. I really appreciate
your help. Here's my entire Main(). It's very short. Can you help me figure
out what I'm doing wrong? THANKS! ...


[STAThread]
static void Main()
{
Process[] ProcessArr =
System.Diagnostics.Process.GetProcessesByName(
System.Diagnostics.Process.GetCurrentProcess().ProcessName
);
Process AlreadyRunningProcess;

//Will never be GREATER THAN 2 by this logic...
// 1 process was the original...
// Process 2 is the one just starting now
if(ProcessArr.Length > 1)
{
//I've tried both [0] AND [1] below
AlreadyRunningProcess = ProcessArr[0];
Control AlreadyRunningMainWind =
Control.FromHandle(AlreadyRunningProcess.MainWindowHandle);

// For text purposes, I've done the next 2 lines.
// Returns NULL string...
string tmpStr = AlreadyRunningProcess.ProcessName;
MessageBox.Show("ProcessName = " + tmpStr);

// AlreadyRunningMainWind is always NULL for some reason!
if(AlreadyRunningMainWind == null)
MessageBox.Show("Window Handle is NULL!");
else
AlreadyRunningMainWind.Focus();
}
else
{
Application.Run(new RunOnlyOnceTestFrm());
}
}


Sijin Joseph said:
Ok here's a thought, when you run the second instance of your application
isn't that also going to have the same process name and get enumerated in
the call to GetProcessByName() so actually you should be checking that
Length > 2, try it. Now you need to correctly identify the already running
process from your current process. That can be done by comparing the process
handles of your current process and the list returned by the
GetProcessByName() method(). Can you also post some sample code if you still
have problems.

--
Sijin Joseph
http://www.indiangeek.net
http://weblogs.asp.net/sjoseph


Hi. You know what? I think I liad before when I said I already had a
reference to the running Process. It's starnge, I'm getting back an array
of
Processes from my
".Process.GetProcessesByName()" call and I'm using the array length to
determine whether the application is already running. Length = 1, this is
the
first one running. Length > 1, it's already running. Now here's where I go
wrong: If I do:

"AlreadyRunningProcess = ProcessArr[0];" where ProcessArr[] was already
filled from my call to ".Process.GetProcessesByName()", what I get back
doesn't seem to work right. If I then try even the simplest
"AlreadyRunningProcess.MachineName" or anything else, I get null values
back.

I've also tried using "AlreadyRunningProcess = ProcessArr[1];" thinking
that
maybe the order of process returned would be backward but NEITHER of these
works.

Can you help further?

Thanks!

:

Give this a shot,

Once you get the Process associated with your application

Control mainWindow = Control.FromHandle(myProcess.MainWindowHandle);

//Then try either
mainWindow.BringToFront();
//Or
mainWindow.Focus();
//Or
mainWindow.Show();

--
Sijin Joseph
http://www.indiangeek.net
http://weblogs.asp.net/sjoseph


How, in .NET Windows Forms applications, can I create an app where, if
the
user double-clicks or otherwise attempts to start the EXE when it's
already
running, it simply brings the already-running application to the front
(standard Windows UI approach). I have figured out how to use the
Process
object to find out if this application is already running and I can
get va
reference to the already-running Process. But how do I make that
Process's
application window/windows come to the front, etc.? And if it can't be
done
because of inter-application security restrctions or some-such, how
does
Microsoft do it?

Thanks for your help!

Alex
 
S

Sijin Joseph

You can also use the class name to find the window, check out these two
tools that should help you find the class name of your main window class.

http://www.codeproject.com/dotnet/wfspy.asp
http://www.codeproject.com/csharp/controlinspector.asp

--
Sijin Joseph
http://www.indiangeek.net
http://weblogs.asp.net/sjoseph


Alex Maghen said:
Oh thank you thank you thank you! Finally, something that works... Now I have
only one little question about this approach and if you can help me with
this, I promise I'll leave you alone (for a little while):

In order for this approach to work, it seems that the application must KNOW
the caption of the main window because it seems it's the only way that it can
use Win32 stuff to FIND the appropriate window to bring to the front. My
problem is, what if I want the caption of the main window to be changeable.
Is there any other value that can be used - maybe something which isn't
displayed to the user but can still be acquired in Win32 in code?

Any ideas would be MUCH appreciated.

Alex

Sijin Joseph said:
Hi Alex,

My mistake, i forgot that Control.FromHandle() only works on handles
belonging to the current process as "Windows" maintains a window table on a
per process basis. So in order to bring your other window to the front you
will have to use some form of Inter Process Communication like windows
messages to communicate to your other instance. I found this article that
uses P/Invoke to bring the previous instance window to the foreground ,
check it out,
http://www.devhood.com/tutorials/tutorial_details.aspx?tutorial_id=711

--
Sijin Joseph
http://www.indiangeek.net
http://weblogs.asp.net/sjoseph


Alex Maghen said:
Hi. Okay well, I still can't seem to solve this problem. I really appreciate
your help. Here's my entire Main(). It's very short. Can you help me figure
out what I'm doing wrong? THANKS! ...


[STAThread]
static void Main()
{
Process[] ProcessArr =
System.Diagnostics.Process.GetProcessesByName(
System.Diagnostics.Process.GetCurrentProcess().ProcessName
);
Process AlreadyRunningProcess;

//Will never be GREATER THAN 2 by this logic...
// 1 process was the original...
// Process 2 is the one just starting now
if(ProcessArr.Length > 1)
{
//I've tried both [0] AND [1] below
AlreadyRunningProcess = ProcessArr[0];
Control AlreadyRunningMainWind =
Control.FromHandle(AlreadyRunningProcess.MainWindowHandle);

// For text purposes, I've done the next 2 lines.
// Returns NULL string...
string tmpStr = AlreadyRunningProcess.ProcessName;
MessageBox.Show("ProcessName = " + tmpStr);

// AlreadyRunningMainWind is always NULL for some reason!
if(AlreadyRunningMainWind == null)
MessageBox.Show("Window Handle is NULL!");
else
AlreadyRunningMainWind.Focus();
}
else
{
Application.Run(new RunOnlyOnceTestFrm());
}
}


:

Ok here's a thought, when you run the second instance of your application
isn't that also going to have the same process name and get
enumerated
in
the call to GetProcessByName() so actually you should be checking that
Length > 2, try it. Now you need to correctly identify the already running
process from your current process. That can be done by comparing the process
handles of your current process and the list returned by the
GetProcessByName() method(). Can you also post some sample code if
you
still
have problems.

--
Sijin Joseph
http://www.indiangeek.net
http://weblogs.asp.net/sjoseph


Hi. You know what? I think I liad before when I said I already had a
reference to the running Process. It's starnge, I'm getting back
an
array
of
Processes from my
".Process.GetProcessesByName()" call and I'm using the array length to
determine whether the application is already running. Length = 1,
this
is
the
first one running. Length > 1, it's already running. Now here's
where
I go
wrong: If I do:

"AlreadyRunningProcess = ProcessArr[0];" where ProcessArr[] was already
filled from my call to ".Process.GetProcessesByName()", what I get back
doesn't seem to work right. If I then try even the simplest
"AlreadyRunningProcess.MachineName" or anything else, I get null values
back.

I've also tried using "AlreadyRunningProcess = ProcessArr[1];" thinking
that
maybe the order of process returned would be backward but NEITHER
of
these
works.

Can you help further?

Thanks!

:

Give this a shot,

Once you get the Process associated with your application

Control mainWindow = Control.FromHandle(myProcess.MainWindowHandle);

//Then try either
mainWindow.BringToFront();
//Or
mainWindow.Focus();
//Or
mainWindow.Show();

--
Sijin Joseph
http://www.indiangeek.net
http://weblogs.asp.net/sjoseph


How, in .NET Windows Forms applications, can I create an app where, if
the
user double-clicks or otherwise attempts to start the EXE when it's
already
running, it simply brings the already-running application to
the
front
(standard Windows UI approach). I have figured out how to use the
Process
object to find out if this application is already running and
I
can
get va
reference to the already-running Process. But how do I make that
Process's
application window/windows come to the front, etc.? And if it can't be
done
because of inter-application security restrctions or
some-such,
how
does
Microsoft do it?

Thanks for your help!

Alex
 
G

Guest

Thanks so much for all your help. I've fugured it all out and I have a sample
with everything cleaned up nice. Anywhere I can upload it for others?

Alex


Sijin Joseph said:
You can also use the class name to find the window, check out these two
tools that should help you find the class name of your main window class.

http://www.codeproject.com/dotnet/wfspy.asp
http://www.codeproject.com/csharp/controlinspector.asp

--
Sijin Joseph
http://www.indiangeek.net
http://weblogs.asp.net/sjoseph


Alex Maghen said:
Oh thank you thank you thank you! Finally, something that works... Now I have
only one little question about this approach and if you can help me with
this, I promise I'll leave you alone (for a little while):

In order for this approach to work, it seems that the application must KNOW
the caption of the main window because it seems it's the only way that it can
use Win32 stuff to FIND the appropriate window to bring to the front. My
problem is, what if I want the caption of the main window to be changeable.
Is there any other value that can be used - maybe something which isn't
displayed to the user but can still be acquired in Win32 in code?

Any ideas would be MUCH appreciated.

Alex

Sijin Joseph said:
Hi Alex,

My mistake, i forgot that Control.FromHandle() only works on handles
belonging to the current process as "Windows" maintains a window table on a
per process basis. So in order to bring your other window to the front you
will have to use some form of Inter Process Communication like windows
messages to communicate to your other instance. I found this article that
uses P/Invoke to bring the previous instance window to the foreground ,
check it out,
http://www.devhood.com/tutorials/tutorial_details.aspx?tutorial_id=711

--
Sijin Joseph
http://www.indiangeek.net
http://weblogs.asp.net/sjoseph


Hi. Okay well, I still can't seem to solve this problem. I really
appreciate
your help. Here's my entire Main(). It's very short. Can you help me
figure
out what I'm doing wrong? THANKS! ...


[STAThread]
static void Main()
{
Process[] ProcessArr =
System.Diagnostics.Process.GetProcessesByName(
System.Diagnostics.Process.GetCurrentProcess().ProcessName
);
Process AlreadyRunningProcess;

//Will never be GREATER THAN 2 by this logic...
// 1 process was the original...
// Process 2 is the one just starting now
if(ProcessArr.Length > 1)
{
//I've tried both [0] AND [1] below
AlreadyRunningProcess = ProcessArr[0];
Control AlreadyRunningMainWind =
Control.FromHandle(AlreadyRunningProcess.MainWindowHandle);

// For text purposes, I've done the next 2 lines.
// Returns NULL string...
string tmpStr = AlreadyRunningProcess.ProcessName;
MessageBox.Show("ProcessName = " + tmpStr);

// AlreadyRunningMainWind is always NULL for some reason!
if(AlreadyRunningMainWind == null)
MessageBox.Show("Window Handle is NULL!");
else
AlreadyRunningMainWind.Focus();
}
else
{
Application.Run(new RunOnlyOnceTestFrm());
}
}


:

Ok here's a thought, when you run the second instance of your
application
isn't that also going to have the same process name and get enumerated
in
the call to GetProcessByName() so actually you should be checking that
Length > 2, try it. Now you need to correctly identify the already
running
process from your current process. That can be done by comparing the
process
handles of your current process and the list returned by the
GetProcessByName() method(). Can you also post some sample code if you
still
have problems.

--
Sijin Joseph
http://www.indiangeek.net
http://weblogs.asp.net/sjoseph


Hi. You know what? I think I liad before when I said I already had a
reference to the running Process. It's starnge, I'm getting back an
array
of
Processes from my
".Process.GetProcessesByName()" call and I'm using the array length to
determine whether the application is already running. Length = 1, this
is
the
first one running. Length > 1, it's already running. Now here's where
I go
wrong: If I do:

"AlreadyRunningProcess = ProcessArr[0];" where ProcessArr[] was
already
filled from my call to ".Process.GetProcessesByName()", what I get
back
doesn't seem to work right. If I then try even the simplest
"AlreadyRunningProcess.MachineName" or anything else, I get null
values
back.

I've also tried using "AlreadyRunningProcess = ProcessArr[1];"
thinking
that
maybe the order of process returned would be backward but NEITHER of
these
works.

Can you help further?

Thanks!

:

Give this a shot,

Once you get the Process associated with your application

Control mainWindow = Control.FromHandle(myProcess.MainWindowHandle);

//Then try either
mainWindow.BringToFront();
//Or
mainWindow.Focus();
//Or
mainWindow.Show();

--
Sijin Joseph
http://www.indiangeek.net
http://weblogs.asp.net/sjoseph


message
How, in .NET Windows Forms applications, can I create an app
where, if
the
user double-clicks or otherwise attempts to start the EXE when
it's
already
running, it simply brings the already-running application to the
front
(standard Windows UI approach). I have figured out how to use the
Process
object to find out if this application is already running and I
can
get va
reference to the already-running Process. But how do I make that
Process's
application window/windows come to the front, etc.? And if it
can't be
done
because of inter-application security restrctions or some-such,
how
does
Microsoft do it?

Thanks for your help!

Alex
 

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