diff --git a/UWPHook/AppManager.cs b/UWPHook/AppManager.cs index ffd5856..cd52f5e 100644 --- a/UWPHook/AppManager.cs +++ b/UWPHook/AppManager.cs @@ -3,6 +3,7 @@ using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Linq; +using System.Management; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; @@ -14,7 +15,8 @@ namespace UWPHook /// static class AppManager { - private static int id; + private static int runningProcessId; + private static bool isLauncherProcess; /// /// Launch a UWP App using a ApplicationActivationManager and sets a internal id to launched proccess id @@ -37,10 +39,16 @@ namespace UWPHook try { mgr.ActivateApplication(aumid, extra_args, ActivateOptions.None, out processId); - - //Bring the launched app to the foreground, this fixes in-home streaming - id = (int)processId; + runningProcessId = (int)processId; + + //if this is a launch aided by GameLaunchHelper, deal with child launch later + var possibleLauncher = Process.GetProcessById(runningProcessId); + if (possibleLauncher.ProcessName.Equals("gamelaunchhelper", StringComparison.OrdinalIgnoreCase)) + { + isLauncherProcess = true; + } + //Bring the launched app to the foreground, this fixes in-home streaming BringProcess(); } catch (Exception e) @@ -56,20 +64,64 @@ namespace UWPHook public static Boolean IsRunning() { //If 0, no app was launched most probably - if (id == 0) - { - return false; - } - try + if (runningProcessId != 0) { - Process.GetProcessById(id); + try + { + Process.GetProcessById(runningProcessId); + return true; + } + catch + { + //the process we launched is no longer running. did it spawn any others? + if (isLauncherProcess) + { + var tree = GetProcessChildren(); + if (tree.TryGetValue(runningProcessId, out var children)) + { + //retarget to the first child we find + isLauncherProcess = false; + + var newId = children.First(); + Debug.WriteLine($"Launcher opened child process ({runningProcessId}->{newId}), using new process as target"); + runningProcessId = newId; + + //bring the "real" launched process + BringProcess(); + return true; + } + } + } } - catch (Exception) + + return false; + } + + /// + /// Find pid<->parent_pid relationships + /// + /// Map of processes to their child IDs. Any process in this object may have already terminated + private static Dictionary> GetProcessChildren() + { + var result = new Dictionary>(); + + using (var searcher = new ManagementObjectSearcher("select processid,parentprocessid from win32_process")) { - return false; + foreach (var process in searcher.Get()) + { + int processId = Convert.ToInt32(process.Properties["processid"].Value); + int parentId = Convert.ToInt32(process.Properties["parentprocessid"].Value); + + if (!result.ContainsKey(parentId)) + { + result.Add(parentId, new List()); + } + + result[parentId].Add(processId); + } } - return true; + return result; } /// @@ -147,8 +199,7 @@ namespace UWPHook         const int SW_SHOWDEFAULT = 10;         */ - var me = Process.GetCurrentProcess(); - var arrProcesses = Process.GetProcessById(id); + var arrProcesses = Process.GetProcessById(runningProcessId); // get the window handle IntPtr hWnd = arrProcesses.MainWindowHandle; diff --git a/UWPHook/UWPHook.csproj b/UWPHook/UWPHook.csproj index 0362c98..08baa9e 100644 --- a/UWPHook/UWPHook.csproj +++ b/UWPHook/UWPHook.csproj @@ -1,4 +1,4 @@ - + @@ -83,6 +83,7 @@ + ..\packages\Microsoft.PowerShell.5.ReferenceAssemblies.1.1.0\lib\net4\System.Management.Automation.dll True