Click here to Skip to main content
15,867,308 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
Hi
In a C# application, how do I bring the instance of an application that was created using Process.Start() to the foreground?

Thanks
K
Posted

Try:
C#
[DllImport("User32.dll")]
private static extern bool SetForegroundWindow(IntPtr hWnd);
private IntPtr handle;
private Process process;
private void button1_Click(object sender, EventArgs e)
    {
    process = Process.Start("cmd");
    }

private void button2_Click(object sender, EventArgs e)
    {
    handle = process.MainWindowHandle;
    SetForegroundWindow(handle);
    }
 
Share this answer
 
Solution 1 will work just fine for your need. But I just wanted to add that if the windows happens to be minimized you will need to use something like this:

C#
[System.Runtime.InteropServices.DllImport("User32.dll")]
private static extern bool SetForegroundWindow(IntPtr handle);
[System.Runtime.InteropServices.DllImport("User32.dll")]
private static extern bool ShowWindow(IntPtr handle, int nCmdShow);
[System.Runtime.InteropServices.DllImport("User32.dll")]
private static extern bool IsIconic(IntPtr handle);

const int SW_RESTORE = 9;

Process proc = Process.Start("cmd.exe");

private void button1_Click(object sender, EventArgs e)
{
    IntPtr handle = proc.MainWindowHandle;
    if (IsIconic(handle))
    {
        ShowWindow(handle, SW_RESTORE);
    }

    SetForegroundWindow(handle);
}
 
Share this answer
 
v2
Comments
ridoy 28-Jan-16 14:55pm    
5ed.
Hi, had the same problem, hope this will help:

The trick is to make windows ‘think’ that our process and the target window (hwnd) are related by attaching the threads (using AttachThreadInput API) and using an alternative API: BringWindowToTop.


Forcing Window/Internet Explorer to the foreground:
C#
private static void ForceForegroundWindow(IntPtr hWnd)
{
    uint foreThread = GetWindowThreadProcessId(GetForegroundWindow(), IntPtr.Zero);
    uint appThread = GetCurrentThreadId();
    const uint SW_SHOW = 5;
 
    if (foreThread != appThread)
    {
        AttachThreadInput(foreThread, appThread, true);
        BringWindowToTop(hWnd);
        ShowWindow(hWnd, SW_SHOW);
        AttachThreadInput(foreThread, appThread, false);
    }
    else
    {
        BringWindowToTop(hWnd);
        ShowWindow(hWnd, SW_SHOW);
    }
}


A more advanced implementation of AttachedThreadInputAction pattern

The idea is to attach to the target process thread and preform an action.

Code Snippet
C#
public static void AttachedThreadInputAction(Action action)
{
    var foreThread = GetWindowThreadProcessId(GetForegroundWindow(), IntPtr.Zero);
    var appThread = GetCurrentThreadId();
    bool threadsAttached = false;
    try
    {
        threadsAttached =
            foreThread == appThread ||
            AttachThreadInput(foreThread, appThread, true);
        if (threadsAttached) action();
        else throw new ThreadStateException("AttachThreadInput failed.");
    }
    finally
    {
        if (threadsAttached)
            AttachThreadInput(foreThread, appThread, false);
    }
}

Usage

Code Snippet
C#
public const uint SW_SHOW = 5;

///<summary>
/// Forces the window to foreground.
///</summary>
///hwnd">The HWND.</param>
public static void ForceWindowToForeground(IntPtr hwnd)
{
    AttachedThreadInputAction(
        () =>
        {
            BringWindowToTop(hwnd);
            ShowWindow(hwnd, SW_SHOW);
        });
}

public static IntPtr SetFocusAttached(IntPtr hWnd)
{
    var result = new IntPtr();
    AttachedThreadInputAction(
        () =>
        {
            result = SetFocus(hWnd);
        });
    return result;
}
 
Share this answer
 
v5
Comments
Besic Denis 3-Apr-13 8:07am    
What about BIG NOTE colored in red on top of article. Did you have problems with stability of application.
ShlomiO 28-Jan-16 6:29am    
Yes we did had problem with this solution in the end.
It seems that windows updates causing this solution not to be stable.
Thank you for your responses. I tried the solution mentioned above, with my application. Still I am not able to bring the newly created process to the foreground, it is still in the background. When I spawn the new process with cmd.exe using the solution provided, it does bring the command prompt to the forgeround.

But when I do the same with my own application, it is still in the background. The gist of what I am trying to do is to create a second instance of the application spawned when the user selects File->Open option in the application, when a file is already opened. This way, the second file will be opened in another instance of the application (similar to MS Word). Below is my code, where MainForm is the main form of my MDI application. The true flag indicates a second instance of the application had to be created.

C#
IntPtr handle;
Process process = 
    Process.Start(typeof(MainForm).Assembly.Location, "true");
    handle = process.MainWindowHandle;
SetForegroundWindow(handle);



Any idea/suggestion, why I am not able to bring the second instance of my application to the foreground is greatly appreciated!

Thanks in advance
K
 
Share this answer
 
v2
Comments
LanFanNinja 7-Nov-11 12:21pm    
I don't know? This code totally works for me

private void button1_Click(object sender, EventArgs e)
{
IntPtr handle;
Process proc =
Process.Start(typeof(MainForm).Assembly.Location, "true");
handle = proc.MainWindowHandle;

if (IsIconic(handle))
{
ShowWindow(handle, SW_RESTORE);
}

SetForegroundWindow(handle);
}

actually it work correctly without the call to SetForegroundWindow(handle);

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900