From: Ludovic Henry Date: Thu, 9 Feb 2017 03:29:03 +0000 (-0500) Subject: [process] Fix Process.GetProcessesByName (#4351) X-Git-Url: http://wien.tomnetworks.com/gitweb/?p=mono.git;a=commitdiff_plain;h=41fced547f724e3eb19a7e4c6ac88b14e702e82c [process] Fix Process.GetProcessesByName (#4351) To get a process by name, we need to access the other process ProcessName, but it can fails on non-win32 platforms. This failure wouldn't be caught in the referencesource implementation trigerring this bug. The exception we would observe would be: Unhandled Exception: System.InvalidOperationException: Process has exited, so the requested information is not available. at System.Diagnostics.Process.get_ProcessName () [0x0002d] in /Users/alexander/dev/mono/mcs/class/System/System.Diagnostics/Process.cs:336 at (wrapper remoting-invoke-with-check) System.Diagnostics.Process:get_ProcessName () at Program.Main (System.String[] args) [0x0003b] in <9c838a66cdc44c81b38c974edcc9c029>:0 [ERROR] FATAL UNHANDLED EXCEPTION: System.InvalidOperationException: Process has exited, so the requested information is not available. at System.Diagnostics.Process.get_ProcessName () [0x0002d] in /Users/alexander/dev/mono/mcs/class/System/System.Diagnostics/Process.cs:336 at (wrapper remoting-invoke-with-check) System.Diagnostics.Process:get_ProcessName () at Program.Main (System.String[] args) [0x0003b] in <9c838a66cdc44c81b38c974edcc9c029>:0 Fixes bug https://bugzilla.xamarin.com/show_bug.cgi?id=52345 --- diff --git a/mcs/class/System/System.Diagnostics/Process.cs b/mcs/class/System/System.Diagnostics/Process.cs index 26a5c1ba93d..8423659fdc7 100644 --- a/mcs/class/System/System.Diagnostics/Process.cs +++ b/mcs/class/System/System.Diagnostics/Process.cs @@ -485,6 +485,34 @@ namespace System.Diagnostics return (new Process (new SafeProcessHandle (proc, false), processId)); } + public static Process[] GetProcessesByName(string processName, string machineName) + { + if (machineName == null) + throw new ArgumentNullException ("machineName"); + + if (!IsLocalMachine (machineName)) + throw new NotImplementedException (); + + Process[] processes = GetProcesses (); + if (processes.Length == 0) + return processes; + + int size = 0; + + for (int i = 0; i < processes.Length; i++) { + try { + if (String.Compare (processName, processes[i].ProcessName, true) == 0) + processes [size++] = processes[i]; + } catch (SystemException) { + /* The process might exit between GetProcesses_internal and GetProcessById */ + } + } + + Array.Resize (ref processes, size); + + return processes; + } + [MethodImplAttribute(MethodImplOptions.InternalCall)] private extern static int[] GetProcesses_internal(); diff --git a/mcs/class/System/Test/System.Diagnostics/ProcessTest.cs b/mcs/class/System/Test/System.Diagnostics/ProcessTest.cs index 20a93a732b6..ac07fdc8bab 100644 --- a/mcs/class/System/Test/System.Diagnostics/ProcessTest.cs +++ b/mcs/class/System/Test/System.Diagnostics/ProcessTest.cs @@ -1113,5 +1113,12 @@ namespace MonoTests.System.Diagnostics } } #endif // MONO_FEATURE_PROCESS_START + + [Test] + public void GetProcessesByName() + { + // This should return Process[0] or a Process[] with all the "foo" programs running + Process.GetProcessesByName ("foo"); + } } } diff --git a/mcs/class/referencesource/System/services/monitoring/system/diagnosticts/Process.cs b/mcs/class/referencesource/System/services/monitoring/system/diagnosticts/Process.cs index 7c5307fa155..2a5432d0ace 100644 --- a/mcs/class/referencesource/System/services/monitoring/system/diagnosticts/Process.cs +++ b/mcs/class/referencesource/System/services/monitoring/system/diagnosticts/Process.cs @@ -1646,6 +1646,7 @@ namespace System.Diagnostics { return GetProcessesByName(processName, "."); } +#if !MONO /// /// /// Creates an array of components that are associated with process resources on a @@ -1671,6 +1672,7 @@ namespace System.Diagnostics { list.CopyTo(temp, 0); return temp; } +#endif /// ///