2 // ProcessTest.cs - NUnit Test Cases for System.Diagnostics.Process
5 // Gert Driesen (drieseng@users.sourceforge.net)
6 // Robert Jordan <robertj@gmx.net>
8 // (C) 2007 Gert Driesen
12 using System.ComponentModel;
13 using System.Diagnostics;
16 using System.Threading;
17 using System.Runtime.InteropServices;
19 using NUnit.Framework;
21 namespace MonoTests.System.Diagnostics
24 public class ProcessTest
26 static bool RunningOnUnix {
28 int p = (int)Environment.OSVersion.Platform;
29 return ((p == 128) || (p == 4) || (p == 6));
34 public void GetProcessById_MachineName_Null ()
37 Process.GetProcessById (1, (string) null);
39 } catch (ArgumentNullException ex) {
40 Assert.AreEqual (typeof (ArgumentNullException), ex.GetType (), "#2");
41 Assert.IsNotNull (ex.Message, "#3");
42 Assert.IsNotNull (ex.ParamName, "#4");
43 Assert.AreEqual ("machineName", ex.ParamName, "#5");
44 Assert.IsNull (ex.InnerException, "#6");
49 public void GetProcesses_MachineName_Null ()
52 Process.GetProcesses ((string) null);
54 } catch (ArgumentNullException ex) {
55 Assert.AreEqual (typeof (ArgumentNullException), ex.GetType (), "#2");
56 Assert.IsNotNull (ex.Message, "#3");
57 Assert.IsNotNull (ex.ParamName, "#4");
58 Assert.AreEqual ("machineName", ex.ParamName, "#5");
59 Assert.IsNull (ex.InnerException, "#6");
63 [Test] // Covers #26363
64 [NUnit.Framework.Category ("MobileNotWorking")]
65 public void GetProcesses_StartTime ()
67 foreach (var p in Process.GetProcesses ()) {
68 if (!p.HasExited && p.StartTime.Year < 1800)
69 Assert.Fail ("Process should not be started since the 18th century.");
74 public void PriorityClass_NotStarted ()
76 Process process = new Process ();
78 process.PriorityClass = ProcessPriorityClass.Normal;
80 } catch (InvalidOperationException ex) {
81 // No process is associated with this object
82 Assert.AreEqual (typeof (InvalidOperationException), ex.GetType (), "#A2");
83 Assert.IsNull (ex.InnerException, "#A3");
84 Assert.IsNotNull (ex.Message, "#A4");
88 Assert.Fail ("#B1:" + process.PriorityClass);
89 } catch (InvalidOperationException ex) {
90 // No process is associated with this object
91 Assert.AreEqual (typeof (InvalidOperationException), ex.GetType (), "#B2");
92 Assert.IsNull (ex.InnerException, "#B3");
93 Assert.IsNotNull (ex.Message, "#B4");
98 public void PriorityClass_Invalid ()
100 Process process = new Process ();
102 process.PriorityClass = (ProcessPriorityClass) 666;
104 } catch (InvalidEnumArgumentException ex) {
105 Assert.AreEqual (typeof (InvalidEnumArgumentException), ex.GetType (), "#2");
106 Assert.IsNull (ex.InnerException, "#3");
107 Assert.IsNotNull (ex.Message, "#4");
108 Assert.IsTrue (ex.Message.IndexOf ("666") != -1, "#5");
109 Assert.IsTrue (ex.Message.IndexOf (typeof (ProcessPriorityClass).Name) != -1, "#6");
110 Assert.IsNotNull (ex.ParamName, "#7");
111 Assert.AreEqual ("value", ex.ParamName, "#8");
115 #if MONO_FEATURE_PROCESS_START
117 public void Start1_FileName_Empty ()
119 Process process = new Process ();
120 process.StartInfo = new ProcessStartInfo (string.Empty);
123 process.StartInfo.UseShellExecute = false;
127 } catch (InvalidOperationException ex) {
128 // Cannot start process because a file name has
130 Assert.AreEqual (typeof (InvalidOperationException), ex.GetType (), "#A2");
131 Assert.IsNull (ex.InnerException, "#A3");
132 Assert.IsNotNull (ex.Message, "#A4");
136 process.StartInfo.UseShellExecute = true;
140 } catch (InvalidOperationException ex) {
141 // Cannot start process because a file name has
143 Assert.AreEqual (typeof (InvalidOperationException), ex.GetType (), "#B2");
144 Assert.IsNull (ex.InnerException, "#B3");
145 Assert.IsNotNull (ex.Message, "#B4");
150 public void Start1_FileName_InvalidPathCharacters ()
153 // on unix, all characters are allowed
154 Assert.Ignore ("Running on Unix.");
156 string systemDir = Environment.GetFolderPath (Environment.SpecialFolder.System);
157 string exe = "\"" + Path.Combine (systemDir, "calc.exe") + "\"";
159 Process process = new Process ();
160 process.StartInfo = new ProcessStartInfo (exe);
163 process.StartInfo.UseShellExecute = false;
164 Assert.IsTrue (process.Start ());
168 process.StartInfo.UseShellExecute = true;
169 Assert.IsTrue (process.Start ());
174 public void Start1_FileName_NotFound ()
176 Process process = new Process ();
177 string exe = RunningOnUnix ? exe = "/usr/bin/shouldnoteverexist"
178 : @"c:\shouldnoteverexist.exe";
180 // absolute path, no shell
181 process.StartInfo = new ProcessStartInfo (exe);
182 process.StartInfo.UseShellExecute = false;
186 } catch (Win32Exception ex) {
187 // The system cannot find the file specified
188 Assert.AreEqual (typeof (Win32Exception), ex.GetType (), "#A2");
189 Assert.AreEqual (-2147467259, ex.ErrorCode, "#A3");
190 Assert.IsNull (ex.InnerException, "#A4");
191 Assert.IsNotNull (ex.Message, "#A5");
192 Assert.AreEqual (2, ex.NativeErrorCode, "#A6");
195 // relative path, no shell
196 process.StartInfo.FileName = "shouldnoteverexist.exe";
197 process.StartInfo.UseShellExecute = false;
201 } catch (Win32Exception ex) {
202 // The system cannot find the file specified
203 Assert.AreEqual (typeof (Win32Exception), ex.GetType (), "#B2");
204 Assert.AreEqual (-2147467259, ex.ErrorCode, "#B3");
205 Assert.IsNull (ex.InnerException, "#B4");
206 Assert.IsNotNull (ex.Message, "#B5");
207 Assert.AreEqual (2, ex.NativeErrorCode, "#B6");
211 Assert.Ignore ("On Unix and Mac OS X, we try " +
212 "to open any file (using xdg-open, ...)" +
213 " and we do not report an exception " +
216 // absolute path, shell
217 process.StartInfo.FileName = exe;
218 process.StartInfo.UseShellExecute = true;
222 } catch (Win32Exception ex) {
223 // The system cannot find the file specified
224 Assert.AreEqual (typeof (Win32Exception), ex.GetType (), "#C2");
225 Assert.AreEqual (-2147467259, ex.ErrorCode, "#C3");
226 Assert.IsNull (ex.InnerException, "#C4");
227 Assert.IsNotNull (ex.Message, "#C5");
228 Assert.AreEqual (2, ex.NativeErrorCode, "#C6");
231 // relative path, shell
232 process.StartInfo.FileName = "shouldnoteverexist.exe";
233 process.StartInfo.UseShellExecute = true;
237 } catch (Win32Exception ex) {
238 // The system cannot find the file specified
239 Assert.AreEqual (typeof (Win32Exception), ex.GetType (), "#D2");
240 Assert.AreEqual (-2147467259, ex.ErrorCode, "#D3");
241 Assert.IsNull (ex.InnerException, "#D4");
242 Assert.IsNotNull (ex.Message, "#D5");
243 Assert.AreEqual (2, ex.NativeErrorCode, "#D6");
248 public void Start1_FileName_Null ()
250 Process process = new Process ();
251 process.StartInfo = new ProcessStartInfo ((string) null);
254 process.StartInfo.UseShellExecute = false;
258 } catch (InvalidOperationException ex) {
259 // Cannot start process because a file name has
261 Assert.AreEqual (typeof (InvalidOperationException), ex.GetType (), "#A2");
262 Assert.IsNull (ex.InnerException, "#A3");
263 Assert.IsNotNull (ex.Message, "#A4");
267 process.StartInfo.UseShellExecute = true;
271 } catch (InvalidOperationException ex) {
272 // Cannot start process because a file name has
274 Assert.AreEqual (typeof (InvalidOperationException), ex.GetType (), "#B2");
275 Assert.IsNull (ex.InnerException, "#B3");
276 Assert.IsNotNull (ex.Message, "#B4");
281 public void Start1_FileName_Whitespace ()
283 Process process = new Process ();
284 process.StartInfo = new ProcessStartInfo (" ");
285 process.StartInfo.UseShellExecute = false;
289 } catch (Win32Exception ex) {
290 // The system cannot find the file specified
291 Assert.AreEqual (typeof (Win32Exception), ex.GetType (), "#2");
292 Assert.AreEqual (-2147467259, ex.ErrorCode, "#3");
293 Assert.IsNull (ex.InnerException, "#4");
294 Assert.IsNotNull (ex.Message, "#5");
295 // TODO: On windows we get ACCESS_DENIED (5) instead of FILE_NOT_FOUND (2) and .NET
296 // gives ERROR_INVALID_PARAMETER (87). See https://bugzilla.xamarin.com/show_bug.cgi?id=44514
297 Assert.IsTrue (ex.NativeErrorCode == 2 || ex.NativeErrorCode == 5 || ex.NativeErrorCode == 87, "#6");
301 [Test] // Start (ProcessStartInfo)
302 public void Start2_FileName_Empty ()
304 ProcessStartInfo startInfo = new ProcessStartInfo (string.Empty);
307 startInfo.UseShellExecute = false;
309 Process.Start (startInfo);
311 } catch (InvalidOperationException ex) {
312 // Cannot start process because a file name has
314 Assert.AreEqual (typeof (InvalidOperationException), ex.GetType (), "#A2");
315 Assert.IsNull (ex.InnerException, "#A3");
316 Assert.IsNotNull (ex.Message, "#A4");
320 startInfo.UseShellExecute = true;
322 Process.Start (startInfo);
324 } catch (InvalidOperationException ex) {
325 // Cannot start process because a file name has
327 Assert.AreEqual (typeof (InvalidOperationException), ex.GetType (), "#B2");
328 Assert.IsNull (ex.InnerException, "#B3");
329 Assert.IsNotNull (ex.Message, "#B4");
333 [Test] // Start (ProcessStartInfo)
334 public void Start2_FileName_NotFound ()
336 ProcessStartInfo startInfo = new ProcessStartInfo ();
337 string exe = RunningOnUnix ? exe = "/usr/bin/shouldnoteverexist"
338 : @"c:\shouldnoteverexist.exe";
340 // absolute path, no shell
341 startInfo.FileName = exe;
342 startInfo.UseShellExecute = false;
344 Process.Start (startInfo);
346 } catch (Win32Exception ex) {
347 // The system cannot find the file specified
348 Assert.AreEqual (typeof (Win32Exception), ex.GetType (), "#A2");
349 Assert.AreEqual (-2147467259, ex.ErrorCode, "#A3");
350 Assert.IsNull (ex.InnerException, "#A4");
351 Assert.IsNotNull (ex.Message, "#A5");
352 Assert.AreEqual (2, ex.NativeErrorCode, "#A6");
355 // relative path, no shell
356 startInfo.FileName = "shouldnoteverexist.exe";
357 startInfo.UseShellExecute = false;
359 Process.Start (startInfo);
361 } catch (Win32Exception ex) {
362 // The system cannot find the file specified
363 Assert.AreEqual (typeof (Win32Exception), ex.GetType (), "#B2");
364 Assert.AreEqual (-2147467259, ex.ErrorCode, "#B3");
365 Assert.IsNull (ex.InnerException, "#B4");
366 Assert.IsNotNull (ex.Message, "#B5");
367 Assert.AreEqual (2, ex.NativeErrorCode, "#B6");
371 Assert.Ignore ("On Unix and Mac OS X, we try " +
372 "to open any file (using xdg-open, ...)" +
373 " and we do not report an exception " +
376 // absolute path, shell
377 startInfo.FileName = exe;
378 startInfo.UseShellExecute = true;
380 Process.Start (startInfo);
382 } catch (Win32Exception ex) {
383 // The system cannot find the file specified
384 Assert.AreEqual (typeof (Win32Exception), ex.GetType (), "#C2");
385 Assert.AreEqual (-2147467259, ex.ErrorCode, "#C3");
386 Assert.IsNull (ex.InnerException, "#C4");
387 Assert.IsNotNull (ex.Message, "#C5");
388 Assert.AreEqual (2, ex.NativeErrorCode, "#C6");
391 // relative path, shell
392 startInfo.FileName = "shouldnoteverexist.exe";
393 startInfo.UseShellExecute = true;
395 Process.Start (startInfo);
397 } catch (Win32Exception ex) {
398 // The system cannot find the file specified
399 Assert.AreEqual (typeof (Win32Exception), ex.GetType (), "#D2");
400 Assert.AreEqual (-2147467259, ex.ErrorCode, "#D3");
401 Assert.IsNull (ex.InnerException, "#D4");
402 Assert.IsNotNull (ex.Message, "#D5");
403 Assert.AreEqual (2, ex.NativeErrorCode, "#D6");
407 [Test] // Start (ProcessStartInfo)
408 public void Start2_FileName_Null ()
410 ProcessStartInfo startInfo = new ProcessStartInfo ((string) null);
413 startInfo.UseShellExecute = false;
415 Process.Start (startInfo);
417 } catch (InvalidOperationException ex) {
418 // Cannot start process because a file name has
420 Assert.AreEqual (typeof (InvalidOperationException), ex.GetType (), "#A2");
421 Assert.IsNull (ex.InnerException, "#A3");
422 Assert.IsNotNull (ex.Message, "#A4");
426 startInfo.UseShellExecute = true;
428 Process.Start (startInfo);
430 } catch (InvalidOperationException ex) {
431 // Cannot start process because a file name has
433 Assert.AreEqual (typeof (InvalidOperationException), ex.GetType (), "#B2");
434 Assert.IsNull (ex.InnerException, "#B3");
435 Assert.IsNotNull (ex.Message, "#B4");
439 [Test] // Start (ProcessStartInfo)
440 public void Start2_FileName_Whitespace ()
442 ProcessStartInfo startInfo = new ProcessStartInfo (" ");
443 startInfo.UseShellExecute = false;
445 Process.Start (startInfo);
447 } catch (Win32Exception ex) {
448 // The system cannot find the file specified
449 Assert.AreEqual (typeof (Win32Exception), ex.GetType (), "#2");
450 Assert.AreEqual (-2147467259, ex.ErrorCode, "#3");
451 Assert.IsNull (ex.InnerException, "#4");
452 Assert.IsNotNull (ex.Message, "#5");
453 // TODO: On windows we get ACCESS_DENIED (5) instead of FILE_NOT_FOUND (2) and .NET
454 // gives ERROR_INVALID_PARAMETER (87). See https://bugzilla.xamarin.com/show_bug.cgi?id=44514
455 Assert.IsTrue (ex.NativeErrorCode == 2 || ex.NativeErrorCode == 5 || ex.NativeErrorCode == 87, "#6");
459 [Test] // Start (ProcessStartInfo)
460 public void Start2_StartInfo_Null ()
463 Process.Start ((ProcessStartInfo) null);
465 } catch (ArgumentNullException ex) {
466 Assert.AreEqual (typeof (ArgumentNullException), ex.GetType (), "#2");
467 Assert.IsNull (ex.InnerException, "#3");
468 Assert.IsNotNull (ex.Message, "#4");
469 Assert.IsNotNull (ex.ParamName, "#5");
470 Assert.AreEqual ("startInfo", ex.ParamName, "#6");
474 [Test] // Start (string)
475 public void Start3_FileName_Empty ()
478 Process.Start (string.Empty);
480 } catch (InvalidOperationException ex) {
481 // Cannot start process because a file name has
483 Assert.AreEqual (typeof (InvalidOperationException), ex.GetType (), "#2");
484 Assert.IsNull (ex.InnerException, "#3");
485 Assert.IsNotNull (ex.Message, "#4");
489 [Test] // Start (string)
490 public void Start3_FileName_NotFound ()
493 Assert.Ignore ("On Unix and Mac OS X, we try " +
494 "to open any file (using xdg-open, ...)" +
495 " and we do not report an exception " +
498 string exe = @"c:\shouldnoteverexist.exe";
500 // absolute path, no shell
504 } catch (Win32Exception ex) {
505 // The system cannot find the file specified
506 Assert.AreEqual (typeof (Win32Exception), ex.GetType (), "#A2");
507 Assert.AreEqual (-2147467259, ex.ErrorCode, "#A3");
508 Assert.IsNull (ex.InnerException, "#A4");
509 Assert.IsNotNull (ex.Message, "#A5");
510 Assert.AreEqual (2, ex.NativeErrorCode, "#A6");
513 // relative path, no shell
515 Process.Start ("shouldnoteverexist.exe");
517 } catch (Win32Exception ex) {
518 // The system cannot find the file specified
519 Assert.AreEqual (typeof (Win32Exception), ex.GetType (), "#B2");
520 Assert.AreEqual (-2147467259, ex.ErrorCode, "#B3");
521 Assert.IsNull (ex.InnerException, "#B4");
522 Assert.IsNotNull (ex.Message, "#B5");
523 Assert.AreEqual (2, ex.NativeErrorCode, "#B6");
527 [Test] // Start (string)
528 public void Start3_FileName_Null ()
531 Process.Start ((string) null);
533 } catch (InvalidOperationException ex) {
534 // Cannot start process because a file name has
536 Assert.AreEqual (typeof (InvalidOperationException), ex.GetType (), "#2");
537 Assert.IsNull (ex.InnerException, "#3");
538 Assert.IsNotNull (ex.Message, "#4");
542 [Test] // Start (string, string)
543 public void Start4_Arguments_Null ()
546 Assert.Ignore ("On Unix and Mac OS X, we try " +
547 "to open any file (using xdg-open, ...)" +
548 " and we do not report an exception " +
551 string exe = @"c:\shouldnoteverexist.exe";
554 Process.Start ("whatever.exe", (string) null);
556 } catch (Win32Exception ex) {
557 // The system cannot find the file specified
558 Assert.AreEqual (typeof (Win32Exception), ex.GetType (), "#B2");
559 Assert.AreEqual (-2147467259, ex.ErrorCode, "#B3");
560 Assert.IsNull (ex.InnerException, "#B4");
561 Assert.IsNotNull (ex.Message, "#B5");
562 Assert.AreEqual (2, ex.NativeErrorCode, "#B6");
566 [Test] // Start (string, string)
567 public void Start4_FileName_Empty ()
570 Process.Start (string.Empty, string.Empty);
572 } catch (InvalidOperationException ex) {
573 // Cannot start process because a file name has
575 Assert.AreEqual (typeof (InvalidOperationException), ex.GetType (), "#2");
576 Assert.IsNull (ex.InnerException, "#3");
577 Assert.IsNotNull (ex.Message, "#4");
581 [Test] // Start (string, string)
582 public void Start4_FileName_NotFound ()
585 Assert.Ignore ("On Unix and Mac OS X, we try " +
586 "to open any file (using xdg-open, ...)" +
587 " and we do not report an exception " +
590 string exe = @"c:\shouldnoteverexist.exe";
592 // absolute path, no shell
594 Process.Start (exe, string.Empty);
596 } catch (Win32Exception ex) {
597 // The system cannot find the file specified
598 Assert.AreEqual (typeof (Win32Exception), ex.GetType (), "#A2");
599 Assert.AreEqual (-2147467259, ex.ErrorCode, "#A3");
600 Assert.IsNull (ex.InnerException, "#A4");
601 Assert.IsNotNull (ex.Message, "#A5");
602 Assert.AreEqual (2, ex.NativeErrorCode, "#A6");
605 // relative path, no shell
607 Process.Start ("shouldnoteverexist.exe", string.Empty);
609 } catch (Win32Exception ex) {
610 // The system cannot find the file specified
611 Assert.AreEqual (typeof (Win32Exception), ex.GetType (), "#B2");
612 Assert.AreEqual (-2147467259, ex.ErrorCode, "#B3");
613 Assert.IsNull (ex.InnerException, "#B4");
614 Assert.IsNotNull (ex.Message, "#B5");
615 Assert.AreEqual (2, ex.NativeErrorCode, "#B6");
620 public void Start_UseShellExecuteWithEmptyUserName ()
623 Assert.Ignore ("On Unix and Mac OS X, we try " +
624 "to open any file (using xdg-open, ...)" +
625 " and we do not report an exception " +
628 string exe = @"c:\shouldnoteverexist.exe";
631 Process p = new Process ();
632 p.StartInfo.FileName = exe;
633 p.StartInfo.UseShellExecute = true;
634 p.StartInfo.UserName = "";
637 } catch (InvalidOperationException) {
639 } catch (Win32Exception) {
643 Process p = new Process ();
644 p.StartInfo.FileName = exe;
645 p.StartInfo.UseShellExecute = true;
646 p.StartInfo.UserName = null;
649 } catch (InvalidOperationException) {
651 } catch (Win32Exception) {
655 [Test] // Start (string, string)
656 public void Start4_FileName_Null ()
659 Process.Start ((string) null, string.Empty);
661 } catch (InvalidOperationException ex) {
662 // Cannot start process because a file name has
664 Assert.AreEqual (typeof (InvalidOperationException), ex.GetType (), "#2");
665 Assert.IsNull (ex.InnerException, "#3");
666 Assert.IsNotNull (ex.Message, "#4");
671 public void StartInfo ()
673 ProcessStartInfo startInfo = new ProcessStartInfo ();
675 Process p = new Process ();
676 Assert.IsNotNull (p.StartInfo, "#A1");
677 p.StartInfo = startInfo;
678 Assert.AreSame (startInfo, p.StartInfo, "#A2");
682 public void StartInfo_Null ()
684 Process p = new Process ();
688 } catch (ArgumentNullException ex) {
689 Assert.AreEqual (typeof (ArgumentNullException), ex.GetType (), "#2");
690 Assert.IsNull (ex.InnerException, "#3");
691 Assert.IsNotNull (ex.Message, "#4");
692 Assert.IsNotNull (ex.ParamName, "#5");
693 Assert.AreEqual ("value", ex.ParamName, "#6");
698 [NUnit.Framework.Category ("NotDotNet")]
699 [NUnit.Framework.Category ("MobileNotWorking")]
700 public void TestRedirectedOutputIsAsync ()
702 // Test requires cygwin, so we just bail out for now.
703 if (Path.DirectorySeparatorChar == '\\')
704 Assert.Ignore ("Test requires cygwin.");
706 Process p = new Process ();
707 p.StartInfo = new ProcessStartInfo ("/bin/sh", "-c \"sleep 2; echo hello\"");
708 p.StartInfo.RedirectStandardOutput = true;
709 p.StartInfo.UseShellExecute = false;
712 Stream stdout = p.StandardOutput.BaseStream;
714 byte [] buffer = new byte [200];
716 // start async Read operation
717 DateTime start = DateTime.Now;
718 IAsyncResult ar = stdout.BeginRead (buffer, 0, buffer.Length,
719 new AsyncCallback (Read), stdout);
721 Assert.IsTrue ((DateTime.Now - start).TotalMilliseconds < 1000, "#01 BeginRead was not async");
723 Assert.AreEqual (0, p.ExitCode, "#02 script failure");
726 ar.AsyncWaitHandle.WaitOne (2000, false);
727 if (bytesRead < "hello".Length)
728 Assert.Fail ("#03 got {0} bytes", bytesRead);
729 Assert.AreEqual ("hello", Encoding.Default.GetString (buffer, 0, 5), "#04");
733 void Read (IAsyncResult ar)
735 Stream stm = (Stream) ar.AsyncState;
736 bytesRead = stm.EndRead (ar);
739 public int bytesRead = -1;
742 [NUnit.Framework.Category ("MobileNotWorking")]
743 // This was for bug #459450
744 public void TestEventRaising ()
746 EventWaitHandle errorClosed = new ManualResetEvent(false);
747 EventWaitHandle outClosed = new ManualResetEvent(false);
748 EventWaitHandle exited = new ManualResetEvent(false);
750 Process p = new Process();
752 p.StartInfo = GetCrossPlatformStartInfo ();
753 p.StartInfo.UseShellExecute = false;
754 p.StartInfo.RedirectStandardOutput = true;
755 p.StartInfo.RedirectStandardError = true;
756 p.StartInfo.RedirectStandardInput = false;
757 p.OutputDataReceived += (object sender, DataReceivedEventArgs e) => {
758 if (e.Data == null) {
763 p.ErrorDataReceived += (object sender, DataReceivedEventArgs e) => {
764 if (e.Data == null) {
769 p.Exited += (object sender, EventArgs e) => {
773 p.EnableRaisingEvents = true;
777 p.BeginErrorReadLine();
778 p.BeginOutputReadLine();
780 Console.WriteLine("started, waiting for handles");
781 bool r = WaitHandle.WaitAll(new WaitHandle[] { errorClosed, outClosed, exited }, 10000, false);
783 Assert.AreEqual (true, r, "Null Argument Events Raised");
787 [NUnit.Framework.Category ("MobileNotWorking")]
788 public void TestEnableEventsAfterExitedEvent ()
790 Process p = new Process ();
792 p.StartInfo = GetCrossPlatformStartInfo ();
793 p.StartInfo.UseShellExecute = false;
794 p.StartInfo.RedirectStandardOutput = true;
795 p.StartInfo.RedirectStandardError = true;
797 var exitedCalledCounter = 0;
798 var exited = new ManualResetEventSlim ();
799 p.Exited += (object sender, EventArgs e) => {
800 exitedCalledCounter++;
801 Assert.IsTrue (p.HasExited);
805 p.EnableRaisingEvents = true;
808 p.BeginErrorReadLine ();
809 p.BeginOutputReadLine ();
813 Assert.AreEqual (1, exitedCalledCounter);
815 Assert.AreEqual (1, exitedCalledCounter);
819 [NUnit.Framework.Category ("MobileNotWorking")]
820 public void TestEnableEventsBeforeExitedEvent ()
822 Process p = new Process ();
824 p.StartInfo = GetCrossPlatformStartInfo ();
825 p.StartInfo.UseShellExecute = false;
826 p.StartInfo.RedirectStandardOutput = true;
827 p.StartInfo.RedirectStandardError = true;
829 p.EnableRaisingEvents = true;
831 var exitedCalledCounter = 0;
832 var exited = new ManualResetEventSlim ();
833 p.Exited += (object sender, EventArgs e) => {
834 exitedCalledCounter++;
835 Assert.IsTrue (p.HasExited);
840 p.BeginErrorReadLine ();
841 p.BeginOutputReadLine ();
844 Assert.IsTrue (exited.Wait (10000));
845 Assert.AreEqual (1, exitedCalledCounter);
847 Assert.AreEqual (1, exitedCalledCounter);
851 [NUnit.Framework.Category ("MobileNotWorking")]
852 public void TestDisableEventsBeforeExitedEvent ()
854 Process p = new Process ();
856 p.StartInfo = GetCrossPlatformStartInfo ();
857 p.StartInfo.UseShellExecute = false;
858 p.StartInfo.RedirectStandardOutput = true;
859 p.StartInfo.RedirectStandardError = true;
861 p.EnableRaisingEvents = false;
863 ManualResetEvent mre = new ManualResetEvent (false);
864 p.Exited += (object sender, EventArgs e) => {
869 p.BeginErrorReadLine ();
870 p.BeginOutputReadLine ();
873 Assert.IsFalse (mre.WaitOne (1000));
876 ProcessStartInfo GetCrossPlatformStartInfo ()
881 path = "/system/bin/ls";
885 return new ProcessStartInfo (path, "/");
887 return new ProcessStartInfo ("help", "");
890 ProcessStartInfo GetEchoCrossPlatformStartInfo ()
895 path = "/system/bin/cat";
899 return new ProcessStartInfo (path);
901 var psi = new ProcessStartInfo ("findstr");
902 psi.Arguments = "\"^\"";
906 #endif // MONO_FEATURE_PROCESS_START
909 public void ProcessName_NotStarted ()
911 Process p = new Process ();
914 String.IsNullOrEmpty (p.ProcessName);
915 } catch (Exception ex) {
919 Assert.IsNotNull (e, "ProcessName should raise if process was not started");
921 //msg should be "No process is associated with this object"
922 Assert.AreEqual (e.GetType (), typeof (InvalidOperationException),
923 "exception should be IOE, I got: " + e.GetType ().Name);
925 Assert.IsNull (e.InnerException, "IOE inner exception should be null");
928 #if MONO_FEATURE_PROCESS_START
930 [NUnit.Framework.Category ("MobileNotWorking")]
931 public void ProcessName_AfterExit ()
933 Process p = new Process ();
934 p.StartInfo = GetCrossPlatformStartInfo ();
935 p.StartInfo.UseShellExecute = false;
936 p.StartInfo.RedirectStandardOutput = true;
937 p.StartInfo.RedirectStandardError = true;
939 p.BeginErrorReadLine();
940 p.BeginOutputReadLine();
942 String.IsNullOrEmpty (p.ExitCode + "");
946 String.IsNullOrEmpty (p.ProcessName);
947 } catch (Exception ex) {
951 Assert.IsNotNull (e, "ProcessName should raise if process was finished");
953 //msg should be "Process has exited, so the requested information is not available"
954 Assert.AreEqual (e.GetType (), typeof (InvalidOperationException),
955 "exception should be IOE, I got: " + e.GetType ().Name);
957 Assert.IsNull (e.InnerException, "IOE inner exception should be null");
959 #endif // MONO_FEATURE_PROCESS_START
962 public void Handle_ThrowsOnNotStarted ()
964 Process p = new Process ();
967 Assert.Fail ("Handle should throw for unstated procs, but returned " + x);
968 } catch (InvalidOperationException) {
973 public void HasExitedCurrent () {
974 Assert.IsFalse (Process.GetCurrentProcess ().HasExited);
977 #if MONO_FEATURE_PROCESS_START
979 [NUnit.Framework.Category ("MobileNotWorking")]
980 public void DisposeWithDisposedStreams ()
982 var psi = GetCrossPlatformStartInfo ();
983 psi.RedirectStandardInput = true;
984 psi.RedirectStandardOutput = true;
985 psi.UseShellExecute = false;
987 var p = Process.Start (psi);
988 p.StandardInput.BaseStream.Dispose ();
989 p.StandardOutput.BaseStream.Dispose ();
994 [NUnit.Framework.Category ("MobileNotWorking")]
995 public void StandardInputWrite ()
997 var psi = GetEchoCrossPlatformStartInfo ();
998 psi.RedirectStandardInput = true;
999 psi.RedirectStandardOutput = true;
1000 psi.UseShellExecute = false;
1002 using (var p = Process.Start (psi)) {
1004 p.OutputDataReceived += (s, e) => {};
1005 p.BeginOutputReadLine ();
1007 for (int i = 0; i < 1024 * 9; ++i) {
1008 p.StandardInput.Write ('x');
1009 if (i > 0 && i % 128 == 0)
1010 p.StandardInput.WriteLine ();
1013 p.StandardInput.Close ();
1018 #endif // MONO_FEATURE_PROCESS_START
1021 public void Modules () {
1022 var modules = Process.GetCurrentProcess ().Modules;
1023 foreach (var a in AppDomain.CurrentDomain.GetAssemblies ()) {
1025 var name = a.GetName ();
1027 StringBuilder sb = new StringBuilder ();
1028 sb.AppendFormat ("Could not found: {0} {1}\n", name.Name, name.Version);
1029 sb.AppendLine ("Looked in modules:");
1031 foreach (var o in modules) {
1032 var m = (ProcessModule) o;
1034 sb.AppendFormat (" {0} {1}.{2}.{3}\n", m.FileName.ToString (),
1035 m.FileVersionInfo.FileMajorPart,
1036 m.FileVersionInfo.FileMinorPart,
1037 m.FileVersionInfo.FileBuildPart);
1039 if (!m.FileName.StartsWith ("[In Memory] " + name.Name))
1042 var fv = m.FileVersionInfo;
1043 if (fv.FileBuildPart != name.Version.Build ||
1044 fv.FileMinorPart != name.Version.Minor ||
1045 fv.FileMajorPart != name.Version.Major)
1051 Assert.IsTrue (found, sb.ToString ());
1055 #if MONO_FEATURE_PROCESS_START
1057 [NUnit.Framework.Category ("MobileNotWorking")]
1058 [ExpectedException (typeof (InvalidOperationException))]
1059 public void TestDoubleBeginOutputReadLine ()
1061 using (Process p = new Process ()) {
1062 p.StartInfo = GetCrossPlatformStartInfo ();
1063 p.StartInfo.UseShellExecute = false;
1064 p.StartInfo.RedirectStandardOutput = true;
1065 p.StartInfo.RedirectStandardError = true;
1069 p.BeginOutputReadLine ();
1070 p.BeginOutputReadLine ();
1077 [NUnit.Framework.Category ("MobileNotWorking")]
1078 [ExpectedException (typeof (InvalidOperationException))]
1079 public void TestDoubleBeginErrorReadLine ()
1081 using (Process p = new Process ()) {
1082 p.StartInfo = GetCrossPlatformStartInfo ();
1083 p.StartInfo.UseShellExecute = false;
1084 p.StartInfo.RedirectStandardOutput = true;
1085 p.StartInfo.RedirectStandardError = true;
1089 p.BeginErrorReadLine ();
1090 p.BeginErrorReadLine ();
1097 [NUnit.Framework.Category ("MobileNotWorking")]
1098 public void TestExitedRaisedTooSoon ()
1101 Assert.Ignore ("using sleep command, only available on unix");
1105 using (Process p = Process.Start("sleep", sleeptime.ToString ())) {
1106 ManualResetEvent mre = new ManualResetEvent (false);
1108 p.EnableRaisingEvents = true;
1109 p.Exited += (sender, e) => {
1113 Assert.IsFalse (mre.WaitOne ((sleeptime - 2) * 1000), "Exited triggered before the process returned");
1116 #endif // MONO_FEATURE_PROCESS_START
1119 public void GetProcessesByName()
1121 // This should return Process[0] or a Process[] with all the "foo" programs running
1122 Process.GetProcessesByName ("foo");
1126 [NUnit.Framework.Category ("NotWorking")] //Getting the name of init works fine on Android and Linux, but fails on OSX, SELinux and iOS
1127 public void HigherPrivilegeProcessName ()
1130 Assert.Ignore ("accessing pid 1, only available on unix");
1132 string v = Process.GetProcessById (1).ProcessName;
1136 [NUnit.Framework.Category ("AndroidNotWorking")] //SELinux makes probing the parent process impossible
1137 public void NonChildProcessWaitForExit ()
1140 Assert.Ignore ("accessing parent pid, only available on unix");
1142 using (Process process = Process.GetProcessById (getppid ()))
1143 using (ManualResetEvent mre = new ManualResetEvent (false))
1145 Assert.IsFalse (process.WaitForExit (10), "#1");
1146 Assert.IsFalse (process.HasExited, "#2");
1147 Assert.Throws<InvalidOperationException>(delegate { int exitCode = process.ExitCode; }, "#3");
1149 process.Exited += (s, e) => mre.Set ();
1150 process.EnableRaisingEvents = true;
1151 Assert.IsFalse (mre.WaitOne (100), "#4");
1153 Assert.IsFalse (process.WaitForExit (10), "#5");
1154 Assert.IsFalse (process.HasExited, "#6");
1155 Assert.Throws<InvalidOperationException>(delegate { int exitCode = process.ExitCode; }, "#7");
1160 [NUnit.Framework.Category ("AndroidNotWorking")] //SELinux makes probing the parent process impossible
1161 public void NonChildProcessName ()
1164 Assert.Ignore ("accessing parent pid, only available on unix");
1166 using (Process process = Process.GetProcessById (getppid ()))
1168 string pname = process.ProcessName;
1169 Assert.IsNotNull (pname, "#1");
1170 AssertHelper.IsNotEmpty (pname, "#2");
1175 [NUnit.Framework.Category ("AndroidNotWorking")] //SELinux makes probing the parent process impossible
1176 public void NonChildProcessId ()
1179 Assert.Ignore ("accessing parent pid, only available on unix");
1182 using (Process process = Process.GetProcessById (ppid = getppid ()))
1184 int pid = process.Id;
1185 Assert.AreEqual (ppid, pid, "#1");
1186 AssertHelper.Greater (pid, 0, "#2");
1190 [DllImport ("libc")]
1191 static extern int getppid();