hey everyone,
our fullscreen Unity 5.0.2f1 Windows 7 (x64) standalone application starts up and runs fine when double-clicking on the app icon - the resolution dialog is hidden by default so the app runs fullscreen and everything runs as expected.
Unfortunately, we have a problem when starting the app via Task Scheduler - it’s an installation so the app is set to start 1 minute after booting up and is the last thing run. The app starts ok but doesn’t get the correct focus. Instead, it starts with the windows taskbar and some other commandline windows showing over the top of it. The player is set to run in the background and fullscreen etc. so the app itself starts working, but obviously we want to get it focused correctly so it’s running in the foreground on top of everything else.
Is this a known problem when a standalone player is started via Task Scheduler or some other batchfile? Are there any commandline arguments we can use to workaround the problem?
We’ve tried using some window focus/show code but it’s not working either. Here’s a modified snippet that tries to get the main window handle for the current process and then switch to it. The problem is that the Unity process is not returning a window handle - the hWnd returned is 0 - so nothing can be switched to. I assumed that we should be able to get a valid hWnd for the Unity player main window handle but the variations of this and other snippets we’ve tried so far always return 0.
Thanks for any info or help.
// greg
Update: hWnd fix. An alternative method for getting the hWnd does return a useful value. I’ve updated the snippet below to help anyone else that stumbles into this.
Update 2: A workaround. Disabling the registry setting that prevents windows from stealing focus and using the updated code snippet below to set the app window to the foreground seems to work. Information on the registry setting is at windows - Preventing applications from stealing focus - Super User. Basically, use regedit to set HKEY_CURRENT_USER > Control Panel > Desktop > ForegroundLockTimeout to 0. This allows the call to SetForegroundWindow(hWnd) to succeed instead of flashing task bar icons and keeping the app in the background.
[DllImport("user32.dll")]
public static extern IntPtr FindWindow(string className, string windowName);
[DllImport("user32.dll")]
internal static extern IntPtr SetForegroundWindow(IntPtr hWnd);
[DllImport("user32.dll")]
internal static extern bool ShowWindow(IntPtr hWnd, int nCmdShow);
private void GetFocusWin() {
// get hWnd, nb. hWnd always seems to return 0 with this method
// http://stackoverflow.com/questions/7357675/how-can-i-set-the-focus-to-application-which-is-allready-in-running-state?rq=1
//System.Diagnostics.Process currentProcess = System.Diagnostics.Process.GetCurrentProcess();
//IntPtr hWnd = currentProcess.MainWindowHandle;
// get hWnd, nb. this works ok on Windows 7 x64
// http://ronniediaz.com/2011/05/03/start-a-process-in-the-foreground-in-c-net-without-appactivate/
IntPtr hWnd = FindWindow(null, "Your App Name");
if (hWnd != IntPtr.Zero) {
Debug.Log("GetFocusWin() setting foreground window, showing window SW_SHOWDEFAULT");
SetForegroundWindow(hWnd);
// enum values from https://msdn.microsoft.com/en-us/library/windows/desktop/ms633548(v=vs.85).aspx
ShowWindow(hWnd, 10); // SW_SHOWDEFAULT = 10, SW_MAXIMIZE = 3, SW_SHOW = 5
} else {
Debug.LogWarning("GetFocusWin() failed, hWnd is 0!");
}
}