From 088eb6d0396fb78565cc9af91a2ddd40d80438c9 Mon Sep 17 00:00:00 2001 From: Francesco Saltori Date: Thu, 3 Jun 2021 21:32:55 +0200 Subject: [PATCH] Replace `ProcessModule.FileName` with `Environment.ProcessPath` and remove `PSUtils.GetMainModule` (#15012) --- .../commands/management/Process.cs | 4 +- .../engine/InitialSessionState.cs | 3 +- .../help/HelpProvider.cs | 3 +- .../security/SecuritySupport.cs | 7 +-- .../utils/FormatAndTypeDataHelper.cs | 2 +- .../utils/PsUtils.cs | 56 ------------------- 6 files changed, 8 insertions(+), 67 deletions(-) diff --git a/src/Microsoft.PowerShell.Commands.Management/commands/management/Process.cs b/src/Microsoft.PowerShell.Commands.Management/commands/management/Process.cs index 1680e17bee..fe291da8eb 100644 --- a/src/Microsoft.PowerShell.Commands.Management/commands/management/Process.cs +++ b/src/Microsoft.PowerShell.Commands.Management/commands/management/Process.cs @@ -649,7 +649,7 @@ namespace Microsoft.PowerShell.Commands { try { - ProcessModule mainModule = PsUtils.GetMainModule(process); + ProcessModule mainModule = process.MainModule; if (mainModule != null) { WriteObject(mainModule.FileVersionInfo, true); @@ -669,7 +669,7 @@ namespace Microsoft.PowerShell.Commands { if (exception.HResult == 299) { - WriteObject(PsUtils.GetMainModule(process).FileVersionInfo, true); + WriteObject(process.MainModule?.FileVersionInfo, true); } else { diff --git a/src/System.Management.Automation/engine/InitialSessionState.cs b/src/System.Management.Automation/engine/InitialSessionState.cs index 17d76cf49b..ae25c8d0ed 100644 --- a/src/System.Management.Automation/engine/InitialSessionState.cs +++ b/src/System.Management.Automation/engine/InitialSessionState.cs @@ -3391,8 +3391,7 @@ namespace System.Management.Automation.Runspaces { // If we can't access the Environment.CurrentDirectory, we may be in an AppContainer. Set the // default drive to $pshome - System.Diagnostics.Process currentProcess = System.Diagnostics.Process.GetCurrentProcess(); - string defaultPath = System.IO.Path.GetDirectoryName(PsUtils.GetMainModule(currentProcess).FileName); + string defaultPath = System.IO.Path.GetDirectoryName(Environment.ProcessPath); context.EngineSessionState.SetLocation(defaultPath, providerContext); } } diff --git a/src/System.Management.Automation/help/HelpProvider.cs b/src/System.Management.Automation/help/HelpProvider.cs index 7e2adbe552..3280a8d254 100644 --- a/src/System.Management.Automation/help/HelpProvider.cs +++ b/src/System.Management.Automation/help/HelpProvider.cs @@ -226,8 +226,7 @@ namespace System.Management.Automation string shellID = this.HelpSystem.ExecutionContext.ShellID; // Beginning in PowerShell 6.0.0.12, the $pshome is no longer registry specified, we search the application base instead. // We use executing assemblies location in case registry entry not found - return Utils.GetApplicationBase(shellID) - ?? Path.GetDirectoryName(PsUtils.GetMainModule(System.Diagnostics.Process.GetCurrentProcess()).FileName); + return Utils.GetApplicationBase(shellID) ?? Path.GetDirectoryName(Environment.ProcessPath); } /// diff --git a/src/System.Management.Automation/security/SecuritySupport.cs b/src/System.Management.Automation/security/SecuritySupport.cs index 4afb15be55..67fc12e2ee 100644 --- a/src/System.Management.Automation/security/SecuritySupport.cs +++ b/src/System.Management.Automation/security/SecuritySupport.cs @@ -248,7 +248,7 @@ namespace System.Management.Automation.Internal while (currentProcess != null) { if (string.Equals(gpScriptPath, - PsUtils.GetMainModule(currentProcess).FileName, StringComparison.OrdinalIgnoreCase)) + currentProcess.MainModule.FileName, StringComparison.OrdinalIgnoreCase)) { foundGpScriptParent = true; break; @@ -1351,9 +1351,8 @@ namespace System.Management.Automation string hostname; try { - var processModule = PsUtils.GetMainModule(currentProcess); - hostname = string.Concat("PowerShell_", processModule.FileName, "_", - processModule.FileVersionInfo.ProductVersion); + hostname = string.Concat("PowerShell_", Environment.ProcessPath, "_", + currentProcess.MainModule.FileVersionInfo.ProductVersion); } catch (ComponentModel.Win32Exception) { diff --git a/src/System.Management.Automation/utils/FormatAndTypeDataHelper.cs b/src/System.Management.Automation/utils/FormatAndTypeDataHelper.cs index d4d877355c..87da1d2a1d 100644 --- a/src/System.Management.Automation/utils/FormatAndTypeDataHelper.cs +++ b/src/System.Management.Automation/utils/FormatAndTypeDataHelper.cs @@ -73,7 +73,7 @@ namespace System.Management.Automation.Runspaces private static string GetBaseFolder(Collection independentErrors) { - return Path.GetDirectoryName(PsUtils.GetMainModule(System.Diagnostics.Process.GetCurrentProcess()).FileName); + return Path.GetDirectoryName(Environment.ProcessPath); } private static string GetAndCheckFullFileName( diff --git a/src/System.Management.Automation/utils/PsUtils.cs b/src/System.Management.Automation/utils/PsUtils.cs index e217a8f478..574f42eace 100644 --- a/src/System.Management.Automation/utils/PsUtils.cs +++ b/src/System.Management.Automation/utils/PsUtils.cs @@ -20,62 +20,6 @@ namespace System.Management.Automation /// internal static class PsUtils { - /// - /// Safely retrieves the MainModule property of a - /// process. Version 2.0 and below of the .NET Framework are - /// impacted by a Win32 API usability knot that throws an - /// exception if API tries to enumerate the process' modules - /// while it is still loading them. This generates the error - /// message: Only part of a ReadProcessMemory or - /// WriteProcessMemory request was completed. - /// The BCL fix in V3 was to just try more, so we do the same - /// thing. - /// - /// Note: If you attempt to retrieve the MainModule of a 64-bit - /// process from a WOW64 (32-bit) process, the Win32 API has a fatal - /// flaw that causes this to return the same error. - /// - /// If you need the MainModule of a 64-bit process from a WOW64 - /// process, you will need to write the P/Invoke yourself. - /// - /// The process from which to - /// retrieve the MainModule - /// - /// You are trying to access the MainModule property for a process that is running - /// on a remote computer. This property is available only for processes that are - /// running on the local computer. - /// - /// - /// The process Id is not available (or) The process has exited. - /// - /// - /// - internal static ProcessModule GetMainModule(Process targetProcess) - { - int caughtCount = 0; - - while (true) - { - try - { - return targetProcess.MainModule; - } - catch (System.ComponentModel.Win32Exception e) - { - // If this is an Access Denied error (which can happen with thread impersonation) - // then re-throw immediately. - if (e.NativeErrorCode == 5) - throw; - - // Otherwise retry to ensure module is loaded. - caughtCount++; - System.Threading.Thread.Sleep(100); - if (caughtCount == 5) - throw; - } - } - } - // Cache of the current process' parentId private static int? s_currentParentProcessId; private static readonly int s_currentProcessId = Environment.ProcessId;