Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -662,7 +662,7 @@ protected override void ProcessRecord()
{
try
{
ProcessModule mainModule = PsUtils.GetMainModule(process);
ProcessModule mainModule = process.MainModule;
if (mainModule != null)
{
WriteObject(mainModule.FileVersionInfo, true);
Expand All @@ -682,7 +682,7 @@ protected override void ProcessRecord()
{
if (exception.HResult == 299)
{
WriteObject(PsUtils.GetMainModule(process).FileVersionInfo, true);
WriteObject(process.MainModule?.FileVersionInfo, true);
}
else
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3365,8 +3365,7 @@ internal static void SetSessionStateDrive(ExecutionContext context, bool setLoca
{
// 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);
}
}
Expand Down
3 changes: 1 addition & 2 deletions src/System.Management.Automation/help/HelpProvider.cs
Original file line number Diff line number Diff line change
Expand Up @@ -226,8 +226,7 @@ internal string GetDefaultShellSearchPath()
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>
Expand Down
7 changes: 3 additions & 4 deletions src/System.Management.Automation/security/SecuritySupport.cs
Original file line number Diff line number Diff line change
Expand Up @@ -248,7 +248,7 @@ private static bool IsCurrentProcessLaunchedByGpScript()
while (currentProcess != null)
{
if (string.Equals(gpScriptPath,
PsUtils.GetMainModule(currentProcess).FileName, StringComparison.OrdinalIgnoreCase))
currentProcess.MainModule.FileName, StringComparison.OrdinalIgnoreCase))
{
foundGpScriptParent = true;
break;
Expand Down Expand Up @@ -1351,9 +1351,8 @@ internal static int Init()
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);
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In a further PR I will remove the need to use Process.MainModule.FileVersionInfo here to avoid loading System.Diagnostics.FileVersionInfo.dll assembly on startup on Windows.

}
catch (ComponentModel.Win32Exception)
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ internal static class FormatAndTypeDataHelper

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(
Expand Down
56 changes: 0 additions & 56 deletions src/System.Management.Automation/utils/PsUtils.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down