Single-instance app: how to force running instance window to foreground?

J

Jen

I've implemented single-instance functionality in my .exe by using the mutex
method. Works great. But when the .exe detects that it is not the first
instance I want to bring the main window of the first instance to the
foreground and set focus to it before the .exe exits. Is this possible
using pure .NET calls or do I need Windows API calls and what are they?
 
G

Guest

There's nothing in the Framework to do what you want, you'll have to PInvoke
SetForegroundWindow. You can use the Process.MainWindowHandle property with
SetForegroundWindow...
 
N

Nicholas Paldino [.NET/C# MVP]

On top of that, the original application will have to make a call
through P/Invoke to the AllowSetForegroundWindow function to allow itself to
be brought to the front.
 
G

Guest

If the application calling SetForegroundWindow is the current foreground
process it should be able to call SetForegroundWindow without
AllowSetForegroundProcess being called. If the application calling
SetForegroundWindow isn't the foreground process (e.g. it doesn't have a
window) then yes, the other application must give permission to the specific
process via AllowSetForegroundProcess.

--
Browse http://connect.microsoft.com/VisualStudio/feedback/ and vote.
http://www.peterRitchie.com/blog/
Microsoft MVP, Visual Developer - Visual C#


Nicholas Paldino said:
On top of that, the original application will have to make a call
through P/Invoke to the AllowSetForegroundWindow function to allow itself to
be brought to the front.


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

Peter Ritchie said:
There's nothing in the Framework to do what you want, you'll have to
PInvoke
SetForegroundWindow. You can use the Process.MainWindowHandle property
with
SetForegroundWindow...
 
N

Nicholas Paldino [.NET/C# MVP]

Well, if the OP is trying to prevent a second instance of his app from
starting, then in the second process, he would call SetForegroundWindow
before the application loop starts (which means he has no window).


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

Peter Ritchie said:
If the application calling SetForegroundWindow is the current foreground
process it should be able to call SetForegroundWindow without
AllowSetForegroundProcess being called. If the application calling
SetForegroundWindow isn't the foreground process (e.g. it doesn't have a
window) then yes, the other application must give permission to the
specific
process via AllowSetForegroundProcess.

--
Browse http://connect.microsoft.com/VisualStudio/feedback/ and vote.
http://www.peterRitchie.com/blog/
Microsoft MVP, Visual Developer - Visual C#


Nicholas Paldino said:
On top of that, the original application will have to make a call
through P/Invoke to the AllowSetForegroundWindow function to allow itself
to
be brought to the front.


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

Peter Ritchie said:
There's nothing in the Framework to do what you want, you'll have to
PInvoke
SetForegroundWindow. You can use the Process.MainWindowHandle property
with
SetForegroundWindow...

--
Browse http://connect.microsoft.com/VisualStudio/feedback/ and vote.
http://www.peterRitchie.com/blog/
Microsoft MVP, Visual Developer - Visual C#


:

I've implemented single-instance functionality in my .exe by using the
mutex
method. Works great. But when the .exe detects that it is not the
first
instance I want to bring the main window of the first instance to the
foreground and set focus to it before the .exe exits. Is this
possible
using pure .NET calls or do I need Windows API calls and what are
they?
 
G

Guest

There's actually a couple of examples of using SetForegroundWindow in .NET
that make no use of AllowSetForegroundWindow:
http://www.codeproject.com/vb/net/A...asp?df=100&forumid=24688&exp=0&select=1101700
http://www.codeproject.com/csharp/oneProcessOnly.asp

I came up with a short example that attempts to call SetForegroundWindow
before the message pump starts:
[STAThread]
static void Main ( )
{
Process[] myProcesses =
Process.GetProcessesByName(Process.GetCurrentProcess().ProcessName);
if(myProcesses != null && myProcesses.Length > 1)
{
foreach (Process process in myProcesses)
{
if (process != Process.GetCurrentProcess())
{
UnsafeNativeMethods.SetForegroundWindow(process.MainWindowHandle);
return;
}
}
}
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new Form1());
}

It seems to always bring up the other application (I only tried 10 times; so
"always" is subjective).

Could be my concept of "foreground process" (in that it has the foreground
window) is flawed. Or, it could be that SetForegroundWindow always works if
a process is attempting a call on SetForegroundWindow on another instance of
the same application and simply isn't documented. Definately a difference in
documentation though (at least my interpretation of it)...

--
Browse http://connect.microsoft.com/VisualStudio/feedback/ and vote.
http://www.peterRitchie.com/blog/
Microsoft MVP, Visual Developer - Visual C#


Nicholas Paldino said:
Well, if the OP is trying to prevent a second instance of his app from
starting, then in the second process, he would call SetForegroundWindow
before the application loop starts (which means he has no window).


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

Peter Ritchie said:
If the application calling SetForegroundWindow is the current foreground
process it should be able to call SetForegroundWindow without
AllowSetForegroundProcess being called. If the application calling
SetForegroundWindow isn't the foreground process (e.g. it doesn't have a
window) then yes, the other application must give permission to the
specific
process via AllowSetForegroundProcess.

--
Browse http://connect.microsoft.com/VisualStudio/feedback/ and vote.
http://www.peterRitchie.com/blog/
Microsoft MVP, Visual Developer - Visual C#


Nicholas Paldino said:
On top of that, the original application will have to make a call
through P/Invoke to the AllowSetForegroundWindow function to allow itself
to
be brought to the front.


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

There's nothing in the Framework to do what you want, you'll have to
PInvoke
SetForegroundWindow. You can use the Process.MainWindowHandle property
with
SetForegroundWindow...

--
Browse http://connect.microsoft.com/VisualStudio/feedback/ and vote.
http://www.peterRitchie.com/blog/
Microsoft MVP, Visual Developer - Visual C#


:

I've implemented single-instance functionality in my .exe by using the
mutex
method. Works great. But when the .exe detects that it is not the
first
instance I want to bring the main window of the first instance to the
foreground and set focus to it before the .exe exits. Is this
possible
using pure .NET calls or do I need Windows API calls and what are
they?
 
P

Peter Duniho

[...]
Could be my concept of "foreground process" (in that it has the
foreground window) is flawed.

That's probably the case. I'm not actually aware of any official
definition of "foreground process", though obviously there must be one for
the documentation to make any sense. However, it seems to me that
"foreground process" could easily include simply the process that was just
started when no other changes to focus has been made. After all, if the
process starting up isn't already the foreground process when it creates
its first window, it's hard to see how the rules would allow its window to
wind up the foreground window. :)
Or, it could be that SetForegroundWindow always works if
a process is attempting a call on SetForegroundWindow on another
instance of the same application and simply isn't documented.

It would be easy enough to test for that condition. Just write a second
application that uses SetForegroundWindow on the first. If indeed there's
a special case for the process being the same application, then using a
second application will result in a failure to set the first application
as the foreground application.

If it works, then that would indicate that indeed a process can be the
foreground process without actually having a window.

Of course, all of this said, IMHO it's a bad idea _generally_ to use
SetForegroundWindow. There's a reason that the rules are complex and
there are many ways for it to not work. That is, it's rude to the user to
bring a new process to the foreground without the user's explicit
instructions or consent.

IMHO, it's almost always better to use SetActiveWindow instead. I think
that in the situation described by the OP the SetForegroundWindow is more
appropriate, but I hope anyone reading through this thread will note that
it's a very specific situation and the solution does not apply to all
other situations.

Pete
 

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