diff --git a/gpii/node_modules/processReporter/dotNetProcesses.csx b/gpii/node_modules/processReporter/dotNetProcesses.csx index 1c8504a49..6eeec6232 100644 --- a/gpii/node_modules/processReporter/dotNetProcesses.csx +++ b/gpii/node_modules/processReporter/dotNetProcesses.csx @@ -33,9 +33,6 @@ public class Startup public async Task Invoke(dynamic input) { ManagementObject[] processes = null; - object propValue; - ProcessModule mainModule; - ProcInfo aProcInfo; ArrayList result; ManagementObjectCollection moc = new ManagementClass(new ManagementPath("Win32_Process")).GetInstances(); @@ -50,68 +47,77 @@ public class Startup processes, p => Convert.ToInt32(p.GetPropertyValue("ProcessId")) == input ); if (aProcess != null) { - result.Add(makeProcInfo(aProcess)); + makeAndAppendProcInfo(aProcess, result); } } else { ManagementObject[] someProcesses = Array.FindAll( processes, p => p.GetPropertyValue("Name").ToString() == input ); foreach (ManagementObject p in someProcesses) { - result.Add(makeProcInfo(p)); + makeAndAppendProcInfo(p, result); } } } // No process specified; get all processes and their info. else { foreach (ManagementObject p in processes) { - result.Add(makeProcInfo(p)); + makeAndAppendProcInfo(p, result); } } return result.ToArray(); } - public static ProcInfo makeProcInfo(ManagementObject process) { + public static void makeAndAppendProcInfo(ManagementObject processMO, ArrayList procInfos) { object propValue; + Process theProcess; + int pid = Convert.ToInt32(processMO.GetPropertyValue("ProcessId")); + // It's possible that the actual process has exited since acquiring its + // ManagementObject representation (the argument passed to this + // function). If so, trying to get its process id (pid) will result in + // an exception indicating the process is no longer running. See: + // https://msdn.microsoft.com/en-us/library/76fkb36k(v=vs.110).aspx#Anchor_1 + try { + theProcess = Process.GetProcessById(pid); + ProcInfo procInfo = new ProcInfo(); + procInfo.command = processMO.GetPropertyValue("Name").ToString(); + procInfo.pid = pid; - ProcInfo procInfo = new ProcInfo(); - procInfo.command = process.GetPropertyValue("Name").ToString(); - procInfo.pid = Convert.ToInt32(process.GetPropertyValue("ProcessId")); - - propValue = process.GetPropertyValue("ExecutablePath"); - if (propValue != null) { - procInfo.fullPath = propValue.ToString(); - } - propValue = process.GetPropertyValue("CommandLine"); - if (propValue == null) { - propValue = ""; - } - procInfo.commandLine = propValue.ToString(); - - // Should be able to get the state of the process using the - // "ExecutionState" property, but that is not implemented; see: - // http://maestriatech.com/wmi.php - // - // Use the Process's main thread's state (the first one). - // Also, map Windows thread states to Linux-y process states. - Process theProcess = Process.GetProcessById(procInfo.pid); - switch (theProcess.Threads[0].ThreadState) { - case ThreadState.Running: - case ThreadState.Wait: - procInfo.state = "Running"; - break; + propValue = processMO.GetPropertyValue("ExecutablePath"); + if (propValue != null) { + procInfo.fullPath = propValue.ToString(); + } + propValue = processMO.GetPropertyValue("CommandLine"); + if (propValue == null) { + propValue = ""; + } + procInfo.commandLine = propValue.ToString(); + // Should be able to get the state of the process using the + // "ExecutionState" property, but that is not implemented; see: + // http://maestriatech.com/wmi.php + // + // Use the Process's main thread's state (the first one). + // Also, map Windows thread states to Linux-y process states. + switch (theProcess.Threads[0].ThreadState) { + case ThreadState.Running: + case ThreadState.Wait: + procInfo.state = "Running"; + break; - case ThreadState.Initialized: - case ThreadState.Ready: - case ThreadState.Standby: - case ThreadState.Transition: - procInfo.state = "Sleeping"; - break; + case ThreadState.Initialized: + case ThreadState.Ready: + case ThreadState.Standby: + case ThreadState.Transition: + procInfo.state = "Sleeping"; + break; - case ThreadState.Terminated: - case ThreadState.Unknown: - procInfo.state = "Zombie"; - break; + case ThreadState.Terminated: + case ThreadState.Unknown: + procInfo.state = "Zombie"; + break; + } + procInfos.Add(procInfo); } - return procInfo; + // Process no longer running -- nothing to add. + catch (ArgumentException e) { } } }