evildictaitor wrote:
public class ForegroundAPI {
///<summary>
///TheFindWindow function retrieves a handle to the top-level window whose class name and window name match the specified strings. This function does not search child windows. This function does not perform a case-sensitive search. To search child windows, beginning with a specified child window, use the FindWindowEx function.
///</summary>
// For Windows Mobile, replace user32.dll with coredll.dll
[DllImport("user32.dll", SetLastError = true)]
static extern IntPtr FindWindow(string lpClassName, string lpWindowName);
// For Windows Mobile, replace user32.dll with coredll.dll
[DllImport("user32.dll")]
[return: MarshalAs(UnmanagedType.Bool)]
static extern bool SetForegroundWindow(IntPtr hWnd);
///<summary>
/// Gets the handle to a window using the case-insensitive title of the Window.
///</summary>
///<param name="windowName">The name of the window to be found (using the Window's title)</param>
///<param name="wait">If true, halts program execution until the window can be found</param>
private static IntPtr FindWindow(string windowName, bool wait)
{
IntPtr hWnd = FindWindow(null, windowName);
while (wait && hWnd == IntPtr.Zero)
{
System.Threading.Thread.Sleep(500);
hWnd = FindWindow(null, windowName);
}
return hWnd;
}
///<summary>
/// Given an hWnd handle to a window, asks Windows to bring the window to the foreground. Returns true on success.
///</summary>
///<param name="windowName">The name of the window to bring to the top</param>
///<param name="wait">If true, halts program execution until the window has been brought to the foreground</param>
public static bool BringWindowToTop(string windowName, bool wait)
{
IntPtr hWnd = FindWindow(windowName, wait);
if (hWnd != 0)
{
return SetForegroundWindow(hWnd);
}
return false;
}
}
public class Program {
public const string WindowPrefix = "MyWindow";
public static void Main(){
bool gotMutex = false;
Mutex winMutex = new Mutex(true,Assembly.GetExecutingAssembly().FullName, out gotMutex);
if(!gotMutex){
ForegroundAPI.BringWindowToTop("MyWindow", true);
return;
}
// this is pretty much the same, but we're extra careful to free up the mutex, even if we crash
// 'cos otherwise you won't be able to start a new app.
try {
Application.Run(new Form1());
} finally {
winMutex.ReleaseMutex();
}
}
}
I've done a similar thing before but used a chunk of shared memory to hold the window handle in.
That way, even if the app messes with its name, you can just grab the handle from the shared memory and use that. (naturally, onstartup if no shared memory is present, store the handle, and onexit delete the shared memory.)