Forcing a window to the foreground ceases to work after logging back in

53 Views Asked by At

I have a small file system listener that opens an EML file in Outlook when it appears in a watched folder. This all works fine.

The installer adds it to the users Startup folder so that it runs in the background when the user logs in.

It tries to force the opened email to the foreground and what is weird is that whilst it works correctly in the following scenarios:

  1. When run either in Release or Debug from with Visual Studio
  2. When run by the installer which starts it upon installation
  3. When started manually when run by double-clicking it in its installed location

if the user logs out or reboots and the App is then started automatically, it behaves OK up to a point in that it opens the email, but it fails to push it to the foreground.

NOTE: If I kill the process via Task Manager and then restart it manually, it works fine!

I have checked via Task Manager that when run in these different ways it is running under the logged in user's account and with the same permissions.

I'm opening the EML using Process.Start as shown here and then passing its handle to the function that tries to push it to the foreground:

  var myProcess = Process.Start(processStartInfo);
  BringWindowToFront(myProcess.MainWindowHandle);

The BringWindowToFront function is taken from code I have found on Stackoverflow and the last two lines may be redundant.

public static void BringWindowToFront(IntPtr WindowHandle)
{
    // Guard: check if window already has focus.
    if (WindowHandle == GetForegroundWindow()) return;

    // Show window maximized.
    ShowWindow(WindowHandle, SHOW_MAXIMIZED);

    // Simulate an "ALT" key press.
    keybd_event((byte)ALT, 0x45, EXTENDEDKEY | 0, 0);

    // Simulate an "ALT" key release.
    keybd_event((byte)ALT, 0x45, EXTENDEDKEY | KEYUP, 0);

    // Show window in forground.
    SetForegroundWindow(WindowHandle);
    SetWindowPos(WindowHandle, (int)HWND_TOPMOST, 0, 0, 0, 0, (int)TOPMOST_FLAGS);
    SetWindowPos(WindowHandle, (int)HWND_NOTOPMOST, 0, 0, 0, 0, (int)TOPMOST_FLAGS);
}

I'm hoping that someone knows why this doesn't work when the App is started at log-in.

STOP PRESS I have since added some logging and found that MyProcess.MainWindowHandle is always zero. Reading around the subject, others have found that you have to wait for the handle to be updated, so I added the following loop. Unfortunately it never breaks out of the loop i.e. the handle remains zero.

        var myProcess = Process.Start(processStartInfo);
        int WndHdl = (int) myProcess.MainWindowHandle;
        while (WndHdl == 0)
        {
            Thread.Sleep(100);
            WndHdl = (int)myProcess.MainWindowHandle;
        }
        WriteToLog("Window handle = " + WndHdl.ToString());
        BringWindowToFront(myProcess.MainWindowHandle);

Am I using the wrong method to get the handle to the window?

0

There are 0 best solutions below