-
Notifications
You must be signed in to change notification settings - Fork 8.1k
Closed
Labels
Resolution-FixedThe issue is fixed.The issue is fixed.WG-Enginecore PowerShell engine, interpreter, and runtimecore PowerShell engine, interpreter, and runtime
Description
The current implementation for getting the parent id of the current process if extremely slow:
The parent Id is not even cached, but is retrieved over and over again. On several systems I see module load times of 5+ seconds, where almost all of the time is spent blocking on the wmi call, waiting for WmiPrvSe to enumerate all processes.
The Id of the process that created us will not change, so cache it and/or use a more efficient method of getting the parent id.
The check for process start time would still have to be done (not in the example).
/// suggested alternative (about 100 times faster)
public static class ProcessInfoUtil
{
public static System.Diagnostics.Process GetParentProcess() { return ParentProcessId == 0 ? null : System.Diagnostics.Process.GetProcessById(ParentProcessId); }
public static readonly int ParentProcessId = GetParentProcessId();
private static int GetParentProcessId()
{
var pi = new PROCESS_BASIC_INFORMATION();
int actual;
if (0 == NativeMethods.NtQueryInformationProcess(new IntPtr(-1), 0/*processbasicInformation*/, ref pi, pi.Size, out actual))
{
return (int)pi.InheritedFromUniqueProcessId;
}
else
{
return 0;
}
}
[StructLayout(LayoutKind.Sequential, Pack = 1)]
private struct PROCESS_BASIC_INFORMATION
{
public IntPtr ExitStatus;
public IntPtr PebBaseAddress;
public IntPtr AffinityMask;
public IntPtr BasePriority;
public UIntPtr UniqueProcessId;
public IntPtr InheritedFromUniqueProcessId;
public int Size { get { return Marshal.SizeOf(typeof(PROCESS_BASIC_INFORMATION));}}
}
static class NativeMethods
{
[DllImport("NtDll", SetLastError=true)]
public static extern int NtQueryInformationProcess(IntPtr ProcessHandle, int processInformationClass, ref PROCESS_BASIC_INFORMATION ProcessInformation, int processInformationLength, out int returnLength);
}
}/// this is the current implementation
string wmiQuery = String.Format(CultureInfo.CurrentCulture,
"Select * From Win32_Process Where Handle='{0}'",
current.Id);
using (CimSession cimSession = CimSession.Create(null))
{
IEnumerable<CimInstance> processCollection =
cimSession.QueryInstances("root/cimv2", "WQL", wmiQuery);
int parentPid =
processCollection.Select(
cimProcess =>
Convert.ToInt32(cimProcess.CimInstanceProperties["ParentProcessId"].Value,
CultureInfo.CurrentCulture)).FirstOrDefault();
if (parentPid == 0)
return null;
...alx9r
Metadata
Metadata
Assignees
Labels
Resolution-FixedThe issue is fixed.The issue is fixed.WG-Enginecore PowerShell engine, interpreter, and runtimecore PowerShell engine, interpreter, and runtime