Switch between two Unity applications

Hi,

I make two Unity applications who called each others, let’s name them “app A” and “app B”.

I coded a script using C# library, as seen as this page. It will switch between apps when clicking on an object.

Here is the code :

public class launchExternalApp : MonoBehaviour {

    /*
     * C# imports from user32.dll
     */
    [System.Runtime.InteropServices.DllImport("user32.dll")]
    public static extern int SetForegroundWindow(IntPtr hwnd);

    [System.Runtime.InteropServices.DllImport("user32.dll")]
    public static extern int SetActiveWindow(IntPtr hwnd);

    [System.Runtime.InteropServices.DllImport("user32.dll")]
    static extern bool ShowWindow(IntPtr hWnd, uint flag);

    [System.Runtime.InteropServices.DllImport("user32.dll")]
    public static extern IntPtr FindWindow(string className, string windowTitle);

    [System.Runtime.InteropServices.DllImport("user32.dll")]
    static extern uint GetWindowThreadProcessId(IntPtr hWnd, out uint processId);
    /**/

    private enum ShowWindowEnum
    {
        Hide = 0,
        ShowNormal = 1, ShowMinimized = 2, ShowMaximized = 3,
        Maximize = 3, ShowNormalNoActivate = 4, Show = 5,
        Minimize = 6, ShowMinNoActivate = 7, ShowNoActivate = 8,
        Restore = 9, ShowDefault = 10, ForceMinimized = 11
    };

    public string windowName = "app_A";
    public string processPathExe ="D:/Unity/Utils/Build/app_a/app_A.exe";

    void OnMouseUpAsButton()
    {
        IntPtr wdwIntPtr = (IntPtr) (-1) ;
        wdwIntPtr = FindWindow(null, windowName);
        
        if (wdwIntPtr == (IntPtr)0)
        {
            Process.Start(processPathExe);
        }
        else
        {
            ShowWindow(wdwIntPtr, (uint)ShowWindowEnum.Show);  // Make the window visible if it was hidden
            ShowWindow(wdwIntPtr, (uint)ShowWindowEnum.Restore);  // Next, restore it if it was minimized
            SetForegroundWindow(wdwIntPtr);  // Finally, activate the window 
        }
        
    }
}

This script works differently according to application window state :

  • If both applications are windowed, this works fine.
  • if one application is windowed and the other one is fullscreen, it works fine.
  • if both are in fullscreen, clicking on the object will flash the other app, then back to my desktop.

There’s a conflict bewteen two fullscreen applications, how can i manage that ?

Thanks,

Hello, i now it’s a bit late but i think i find a way to avoid the “flash” when switching focus. You just have to slightly delay your ShowWindow method.

Indeed i experienced the same issues and after using this delay no more flash.

private void FocusProcess(Process process)
{
    var launchTime = DateTime.Now.TimeOfDay - process.StartTime.TimeOfDay;
    Debug.Log("Process launch time" + launchTime);
    if (launchTime.Seconds > processFocusDelay)
    {
        // Immediate Focus
        Debug.Log("Immediate Focus");
        StartCoroutine(DelayProcess(process, 1));
    }
    else
    {
        // Focus after the process focus delay is over
        int remainingTime = Mathf.RoundToInt(processFocusDelay - launchTime.Seconds);
        Debug.Log("Delayed Focus : " + remainingTime);
        StartCoroutine(DelayProcess(process, remainingTime));
    }
}

private IEnumerator DelayProcess(Process process, int delay)
{
    yield return new WaitForSeconds(delay);
    Debug.Log("Focus");
    IntPtr hWnd = FindWindow(null, process.ProcessName);
    ShowWindow(hWnd, 3);
}

As you can see in the example above even if i want to “immediately” focus my new process i wait for 1 seconds before focus.
I think it’s possible to wait lesser than 1 sec but it work for me !

With Love, Skuuulzy