From f54085f8a3947e9b3911632d7ee69ee7d15532a3 Mon Sep 17 00:00:00 2001 From: Christoph Bergmeister Date: Tue, 5 Jun 2018 12:44:45 +0000 Subject: [PATCH] Create JumpList in background thread to improve performance (#6985) * Perform JumpList creation in background thread to improve performance when pwsh owns the window (i.e. when the Jumplist has to be created) * Move JumpList creation to a later stage to allow for more code that might make it exit earlier as suggested in PR review by @iSazonov --- .../WindowsTaskbarJumpList/TaskbarJumpList.cs | 3 ++- .../host/msh/ConsoleHost.cs | 15 +++++++++++---- 2 files changed, 13 insertions(+), 5 deletions(-) diff --git a/src/Microsoft.PowerShell.ConsoleHost/WindowsTaskbarJumpList/TaskbarJumpList.cs b/src/Microsoft.PowerShell.ConsoleHost/WindowsTaskbarJumpList/TaskbarJumpList.cs index 95096d91d..69e4e264f 100644 --- a/src/Microsoft.PowerShell.ConsoleHost/WindowsTaskbarJumpList/TaskbarJumpList.cs +++ b/src/Microsoft.PowerShell.ConsoleHost/WindowsTaskbarJumpList/TaskbarJumpList.cs @@ -12,7 +12,8 @@ namespace Microsoft.PowerShell { internal static void CreateElevatedEntry(string title) { - // check startupInfo to know if the current shell owns a window before proceeding + // Check startupInfo first to know if the current shell is interactive and owns a window before proceeding + // This check is fast (less than 1ms) and allows for quick-exit GetStartupInfo(out StartUpInfo startupInfo); var STARTF_USESHOWWINDOW = 0x00000001; var SW_HIDE = 0; diff --git a/src/Microsoft.PowerShell.ConsoleHost/host/msh/ConsoleHost.cs b/src/Microsoft.PowerShell.ConsoleHost/host/msh/ConsoleHost.cs index 02a8c1453..c279d0cce 100644 --- a/src/Microsoft.PowerShell.ConsoleHost/host/msh/ConsoleHost.cs +++ b/src/Microsoft.PowerShell.ConsoleHost/host/msh/ConsoleHost.cs @@ -26,6 +26,7 @@ using System.Management.Automation.Language; using Dbg = System.Management.Automation.Diagnostics; using ConsoleHandle = Microsoft.Win32.SafeHandles.SafeFileHandle; using System.Management.Automation.Tracing; +using System.Threading.Tasks; #if LEGACYTELEMETRY using Microsoft.PowerShell.Telemetry.Internal; #endif @@ -120,10 +121,6 @@ namespace Microsoft.PowerShell } #endif -#if !UNIX - Microsoft.PowerShell.TaskbarJumpList.CreateElevatedEntry(ConsoleHostStrings.RunAsAdministrator); -#endif - // put PSHOME in front of PATH so that calling `powershell` within `powershell` always starts the same running version string path = Environment.GetEnvironmentVariable("PATH"); if (path != null) @@ -214,6 +211,16 @@ namespace Microsoft.PowerShell return ExitCodeBadCommandLineParameter; } +#if !UNIX + // Creating a JumpList entry takes around 55ms when the PowerShell process is interactive and + // owns the current window (otherwise it does a fast exit anyway). Since there is no 'GET' like API, + // we always have to execute this call because we do not know if it has been created yet. + // The JumpList does persist as long as the filepath of the executable does not change but there + // could be disruptions to it like e.g. the bi-annual Windows update, we decided to + // not over-optimize this and always create the JumpList as a non-blocking background task instead. + Task.Run(() => TaskbarJumpList.CreateElevatedEntry(ConsoleHostStrings.RunAsAdministrator)); +#endif + // First check for and handle PowerShell running in a server mode. if (s_cpp.ServerMode) {