Replace ProcessModule.FileName with Environment.ProcessPath and remove PSUtils.GetMainModule (#15012)

This commit is contained in:
Francesco Saltori
2021-06-03 12:32:55 -07:00
committed by GitHub
parent 50d850740b
commit 088eb6d039
6 changed files with 8 additions and 67 deletions
@@ -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
{
@@ -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);
}
}
@@ -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);
}
/// <summary>
@@ -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)
{
@@ -73,7 +73,7 @@ namespace System.Management.Automation.Runspaces
private static string GetBaseFolder(Collection<string> independentErrors)
{
return Path.GetDirectoryName(PsUtils.GetMainModule(System.Diagnostics.Process.GetCurrentProcess()).FileName);
return Path.GetDirectoryName(Environment.ProcessPath);
}
private static string GetAndCheckFullFileName(
@@ -20,62 +20,6 @@ namespace System.Management.Automation
/// </summary>
internal static class PsUtils
{
/// <summary>
/// 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.
/// </summary>
/// <param name="targetProcess">The process from which to
/// retrieve the MainModule</param>
/// <exception cref="NotSupportedException">
/// 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.
/// </exception>
/// <exception cref="InvalidOperationException">
/// The process Id is not available (or) The process has exited.
/// </exception>
/// <exception cref="System.ComponentModel.Win32Exception">
/// </exception>
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;