Search Unity

Run another application in backround without lose focus and minimize (silent run in background)

Discussion in 'Scripting' started by ludum_mubul, Jan 13, 2017.

  1. ludum_mubul

    ludum_mubul

    Joined:
    Dec 9, 2016
    Posts:
    27
    Hi!

    Here is little task description.
    I have two applications app1 and app2.
    app1 is running in fullscreen mode and launching app2 using Process(), but when app2 is started, app1 focus is lost and app1 is minimized.

    How to prevent app1 lose focus and minimize, when app2 is launched?

    So in best case app1 running in fullscreen, then launching app2 and app1 still in fullscreenmode without focus lost.

    Thanks in advance!
     
  2. AndyGainey

    AndyGainey

    Joined:
    Dec 2, 2015
    Posts:
    216
    Have you looked into the options provided by Process.StartInfo? In particular, WindowStyle? Either Minimized or Hidden might achieve what you want.
     
    Airmouse likes this.
  3. ludum_mubul

    ludum_mubul

    Joined:
    Dec 9, 2016
    Posts:
    27
    Hi Andy!
    Yes, I tried this. With minimized window style focus switched from app1 to app2 and then app2 minimized.
    With hidden window style app2 window is hidden, but app1 still losing focus.
    So, if app1 will be in fullscreen, then it will minimize in moment, when window for app2 is created and I have to switch on app1 manualy.
    Maybe need additional setup for app1 and app2 in unity?

    Best regards!
     
  4. ludum_mubul

    ludum_mubul

    Joined:
    Dec 9, 2016
    Posts:
    27
  5. ludum_mubul

    ludum_mubul

    Joined:
    Dec 9, 2016
    Posts:
    27
  6. ludum_mubul

    ludum_mubul

    Joined:
    Dec 9, 2016
    Posts:
    27
    Is it possible at all?
    Anyone?
     
  7. AndyGainey

    AndyGainey

    Joined:
    Dec 2, 2015
    Posts:
    216
    I'm sure it's possible, but might require more work. And depends on your platform and the nature of the second program you're trying to run in the background.

    Are you targeting just a single platform? On Windows at least, a quick searching around suggested that this will happen only if the first program currently has focus and the second program creates a window. If possible, just try making the second program to not create a window. Or if that's not possible or desirable, you might be able to make an intermediate program that has no window and does nothing other than launch the second program. So the first program spawns the intermediate program but doesn't lose focus because the spawned program doesn't create a window. Then the intermediate program spawns the intended second program, which also doesn't steal focus because its spawning program didn't have focus to begin with. I'm not sure about that behavior; just theoretical based on some searching and generic reasoning, but it might be worth an experiment.
     
  8. ludum_mubul

    ludum_mubul

    Joined:
    Dec 9, 2016
    Posts:
    27
    Both apps are targeted to windows desktop and created in Unity.
    Is it possible in unity to create app without window?
    Btw, thanks for idea with intermediate program. Will check this.
    Thanks!
     
  9. AndyGainey

    AndyGainey

    Joined:
    Dec 2, 2015
    Posts:
    216
    Check the command line options for the standalone player. The obvious options to try are "-nographics" or "-batchmode".
     
  10. ludum_mubul

    ludum_mubul

    Joined:
    Dec 9, 2016
    Posts:
    27
    Both options not fit, because app2 is for htc vive, so it should accept input and display in hmd.
    But thanks for response!
     
  11. ludum_mubul

    ludum_mubul

    Joined:
    Dec 9, 2016
    Posts:
    27
    So I've found the solution.
    1. Run app1 with keys -popupwindow -screen-height %full_height% -screen-width %full_width%
    2. In app1 create process with minimized or hidden WindowStyle option in Process.StartInfo.
    3. In app2 add next code:

    "VideosSelector" - Caption on main form of app1.

    Code (CSharp):
    1. using UnityEngine;
    2. using System.Collections;
    3. using UnityEngine.VR;
    4. using System.Runtime.InteropServices;
    5. using System;
    6. using System.Diagnostics;
    7. using System.Threading;
    8. using System.Collections.Generic;
    9. using System.Text;
    10.  
    11. public class CMDFilesToPlay : MonoBehaviour {
    12.  
    13.     void Awake()
    14.     {
    15.         var videosSelectors = FindWindowsWithText("VideosSelector");
    16.         foreach (IntPtr hwnd in videosSelectors)
    17.         {
    18.             Thread.Sleep(100);
    19.             SetForegroundWindow(hwnd);
    20.             break;
    21.         }
    22.     }
    23.  
    24.     [DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
    25.     public static extern bool SetForegroundWindow(IntPtr hWnd);
    26.  
    27.     [DllImport("user32.dll", CharSet = CharSet.Unicode)]
    28.     private static extern int GetWindowText(IntPtr hWnd, StringBuilder strText, int maxCount);
    29.  
    30.     [DllImport("user32.dll", CharSet = CharSet.Unicode)]
    31.     private static extern int GetWindowTextLength(IntPtr hWnd);
    32.  
    33.     [DllImport("user32.dll")]
    34.     private static extern bool EnumWindows(EnumWindowsProc enumProc, IntPtr lParam);
    35.  
    36.     // Delegate to filter which windows to include
    37.     public delegate bool EnumWindowsProc(IntPtr hWnd, IntPtr lParam);
    38.  
    39.     /// <summary> Get the text for the window pointed to by hWnd </summary>
    40.     public static string GetWindowText(IntPtr hWnd)
    41.     {
    42.         int size = GetWindowTextLength(hWnd);
    43.         if (size > 0)
    44.         {
    45.             var builder = new StringBuilder(size + 1);
    46.             GetWindowText(hWnd, builder, builder.Capacity);
    47.             return builder.ToString();
    48.         }
    49.  
    50.         return String.Empty;
    51.     }
    52.  
    53.     /// <summary> Find all windows that match the given filter </summary>
    54.     /// <param name="filter"> A delegate that returns true for windows
    55.     ///    that should be returned and false for windows that should
    56.     ///    not be returned </param>
    57.     public static IEnumerable<IntPtr> FindWindows(EnumWindowsProc filter)
    58.     {
    59.         IntPtr found = IntPtr.Zero;
    60.         List<IntPtr> windows = new List<IntPtr>();
    61.  
    62.         EnumWindows(delegate(IntPtr wnd, IntPtr param)
    63.         {
    64.             if (filter(wnd, param))
    65.             {
    66.                 // only add the windows that pass the filter
    67.                 windows.Add(wnd);
    68.             }
    69.  
    70.             // but return true here so that we iterate all windows
    71.             return true;
    72.         }, IntPtr.Zero);
    73.  
    74.         return windows;
    75.     }
    76.  
    77.     /// <summary> Find all windows that contain the given title text </summary>
    78.     /// <param name="titleText"> The text that the window title must contain. </param>
    79.     public static IEnumerable<IntPtr> FindWindowsWithText(string titleText)
    80.     {
    81.         return FindWindows(delegate(IntPtr wnd, IntPtr param)
    82.         {
    83.             return GetWindowText(wnd).Contains(titleText);
    84.         });
    85.     }
    86. }
    87.  
     
    AndyGainey likes this.