A bit of background on what I am making first. It is a C# based launcher program which allows easy switching between the main home theatre media players (in my case, Plex, MediaPortal and Kodi), so that they can all be used for their individual merits (Plex for downloaded content, MediaPortal for TV recordings and live TV, and Kodi for everything else, usually streaming).
These applications are suspended using pssuspend which means they can all stay open at once, which is great for slow computers.
Users press a button (on their remote) to switch back to the launcher to choose another application.
I am almost at a usable version but I have had an issue for a while that I've narrowed down.
If my launcher switches into an application (using the methods mentioned below), I cannot switch back to my launchers process.
This only happens when:
At all other times, everything works as expected.
To switch, I am currently using SwitchToThisWindow(IntPtr hWnd, bool fAltTab)
(from http://www.pinvoke.net/default.aspx/user32/SwitchToThisWindow.html).
I have also used Microsoft.VisualBasic.Interaction.AppActivate
(from http://msdn.microsoft.com/en-us/library/x9784w8e(v=vs.100).aspx?cs-save-lang=1&cs-lang=csharp#code-snippet-1).
Both of these have the same results.
Things I have confirmed are NOT related to the issue:
Something that shouldn't be an issue but should be noted just in case, is that the frontend of the launcher is all using CefSharp (CEF is an integrated version of the Chrome browser). Although the issue was occurring before this was added.
My Potential thoughts:
AppActivate
, I realised the UIPermission level may matter, however setting it manually to full trust doesn't make any change.Some code of my app switching in context:
[DllImport("user32.dll", SetLastError = true)]
static extern void SwitchToThisWindow(IntPtr hWnd, bool fAltTab);
static Process currentProcess = Process.GetCurrentProcess();
public static void SwitchToApplication(Process toSwitchTo)
{
SwitchProcess(toSwitchTo);
}
public static void SwitchToLauncher()
{
FrontendBridge.GetInstance().Reset();
SwitchProcess(Process.GetCurrentProcess());
Taskbar.Hide();
}
private static void SwitchProcess(Process toSwitchTo)
{
if (currentProcess == toSwitchTo)
return;
if (toSwitchTo.MainWindowHandle != IntPtr.Zero)
{
SwitchToThisWindow(toSwitchTo.MainWindowHandle,true);
}
currentProcess = toSwitchTo;
}
Hopefully someone has some ideas or has had a similar issue in the past.
Please let me know if you need any additional information or bits of source code.
So I managed to fix this.
It turns out the issue isn't due to any of my code surrounding those API calls, or the applications that were being switched to themselves.
The breakthrough answer was from here:
http://www.codeproject.com/Tips/76427/How-to-bring-window-to-top-with-SetForegroundWindo
This explained how when debugging you are allowed to set foreground window, but without debugging the window must be the last one to get keyboard input or else it won't have focus.
The solution was for code to hold the alt key to have windows allow my program to set the foreground window, then SetForegroundWindow or SwitchToThisWindow (I had better results with this one when switching to something that may not be open yet) could be used.
I found an example of someone using this code here:
http://csharpapprentice.blogspot.co.nz/2013/03/ok-ok-its-c.html