Wednesday, June 30, 2010

Making your WPF application single instance

I used the ideas in this article. However, when bringing my
application to the top, I used my own methods. Below is the link to
the article, and the code that I used.

However, I used the following:
In my Startup.cs file I did the following:

static Mutex mutex = new Mutex(true,
public static void Main()
if (mutex.WaitOne(TimeSpan.Zero, true))
MyApp app = new MyApp
// send our Win32 message to make the currently
running instance
// jump on top of all the other windows
catch (Exception e)
{//Catch all un-handle exception from the application


And in my NativeMethods.cs I did the following:
[DllImport("User32", EntryPoint = "FindWindow")]
public static extern IntPtr FindWindow(string lpClassName, string

[DllImport("User32", EntryPoint = "BringWindowToTop")]
public static extern bool BringWindowToTop(IntPtr wHandle);

[DllImport("User32", EntryPoint = "SetForegroundWindow")]
public static extern bool SetForegroundWindow(IntPtr wHandle);

[DllImport("User32", EntryPoint = "SetFocus")]
public static extern bool SetFocus(IntPtr wHandle);

static extern bool ShowWindow(IntPtr hWnd, int nCmdShow);

public static void BringTMForeGround()
bool ret = false;
IntPtr hWnd = NativeMethods.FindWindow(null, "Title of
Application Window"); // Get Window of App2

if (hWnd == IntPtr.Zero)
FindWindowLike.Window[] list = FindWindowLike.Find(0, "Title
of Application Window", "");
if (list.Length >= 1)
hWnd = (IntPtr)list[0].Handle;
if (hWnd != IntPtr.Zero) // Check if App2 exists
ret = NativeMethods.SetForegroundWindow(hWnd);
ret = NativeMethods.ShowWindow(hWnd, 9);
ret = NativeMethods.BringWindowToTop(hWnd);
//ret = SetFocus(hWnd);
catch (Exception)

The function FindWinowLike was another class and this is whats in it:
using System;
using System.Collections;
using System.Runtime.InteropServices;
using System.Text;

namespace MyAppNamespace
public class FindWindowLike

public class Window
public string Title;
public string Class;
public int Handle;

private static extern int GetWindow(int hwnd, int wCmd);

private static extern int GetDesktopWindow();

[DllImport("user32", EntryPoint = "GetWindowLongA")]
private static extern int GetWindowLong(int hwnd, int nIndex);

private static extern int GetParent(int hwnd);

[DllImport("user32", EntryPoint = "GetClassNameA")]
private static extern int GetClassName(
int hWnd, [Out] StringBuilder lpClassName, int nMaxCount);

[DllImport("user32", EntryPoint = "GetWindowTextA")]
private static extern int GetWindowText(
int hWnd, [Out] StringBuilder lpString, int nMaxCount);

private const int GWL_ID = (-12);
private const int GW_HWNDNEXT = 2;
private const int GW_CHILD = 5;

public static Window[] Find(int hwndStart, string findText, string

ArrayList windows = DoSearch(hwndStart, findText, findClassName);

return (Window[])windows.ToArray(typeof(Window));

} //Find

private static ArrayList DoSearch(int hwndStart, string findText,
string findClassName)

ArrayList list = new ArrayList();

if (hwndStart == 0)
hwndStart = GetDesktopWindow();

int hwnd = GetWindow(hwndStart, GW_CHILD);

while (hwnd != 0)

// Recursively search for child windows.
list.AddRange(DoSearch(hwnd, findText, findClassName));

StringBuilder text = new StringBuilder(255);
int rtn = GetWindowText(hwnd, text, 255);
string windowText = text.ToString();
windowText = windowText.Substring(0, rtn);

StringBuilder cls = new StringBuilder(255);
rtn = GetClassName(hwnd, cls, 255);
string className = cls.ToString();
className = className.Substring(0, rtn);

if (GetParent(hwnd) != 0)
rtn = GetWindowLong(hwnd, GWL_ID);

if (windowText.Length > 0 && windowText.StartsWith(findText) &&
(className.Length == 0 || className.StartsWith(findClassName)))
Window currentWindow = new Window();

currentWindow.Title = windowText;
currentWindow.Class = className;
currentWindow.Handle = hwnd;


hwnd = GetWindow(hwnd, GW_HWNDNEXT);


return list;

} //DoSearch

} //Class


No comments: