[process] Disable tests that do not work on mobile (#4598)
[mono.git] / mcs / class / System / Test / System.Diagnostics / ProcessTest.cs
1 //
2 // ProcessTest.cs - NUnit Test Cases for System.Diagnostics.Process
3 //
4 // Authors:
5 //   Gert Driesen (drieseng@users.sourceforge.net)
6 //   Robert Jordan <robertj@gmx.net>
7 //
8 // (C) 2007 Gert Driesen
9 // 
10
11 using System;
12 using System.ComponentModel;
13 using System.Diagnostics;
14 using System.IO;
15 using System.Text;
16 using System.Threading;
17 using System.Runtime.InteropServices;
18
19 using NUnit.Framework;
20
21 namespace MonoTests.System.Diagnostics
22 {
23         [TestFixture]
24         public class ProcessTest
25         {
26                 static bool RunningOnUnix {
27                         get {
28                                 int p = (int)Environment.OSVersion.Platform;
29                                 return ((p == 128) || (p == 4) || (p == 6));
30                         }
31                 }
32
33                 [Test]
34                 public void GetProcessById_MachineName_Null ()
35                 {
36                         try {
37                                 Process.GetProcessById (1, (string) null);
38                                 Assert.Fail ("#1");
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");
45                         }
46                 }
47
48                 [Test]
49                 public void GetProcesses_MachineName_Null ()
50                 {
51                         try {
52                                 Process.GetProcesses ((string) null);
53                                 Assert.Fail ("#1");
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");
60                         }
61                 }
62
63                 [Test] // Covers #26363
64                 [NUnit.Framework.Category ("MobileNotWorking")]
65                 public void GetProcesses_StartTime ()
66                 {
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.");
70                         }
71                 }
72
73                 [Test]
74                 public void PriorityClass_NotStarted ()
75                 {
76                         Process process = new Process ();
77                         try {
78                                 process.PriorityClass = ProcessPriorityClass.Normal;
79                                 Assert.Fail ("#A1");
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");
85                         }
86
87                         try {
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");
94                         }
95                 }
96
97                 [Test]
98                 public void PriorityClass_Invalid ()
99                 {
100                         Process process = new Process ();
101                         try {
102                                 process.PriorityClass = (ProcessPriorityClass) 666;
103                                 Assert.Fail ("#1");
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");
112                         }
113                 }
114
115 #if MONO_FEATURE_PROCESS_START
116                 [Test] // Start ()
117                 public void Start1_FileName_Empty ()
118                 {
119                         Process process = new Process ();
120                         process.StartInfo = new ProcessStartInfo (string.Empty);
121
122                         // no shell
123                         process.StartInfo.UseShellExecute = false;
124                         try {
125                                 process.Start ();
126                                 Assert.Fail ("#A1");
127                         } catch (InvalidOperationException ex) {
128                                 // Cannot start process because a file name has
129                                 // not been provided
130                                 Assert.AreEqual (typeof (InvalidOperationException), ex.GetType (), "#A2");
131                                 Assert.IsNull (ex.InnerException, "#A3");
132                                 Assert.IsNotNull (ex.Message, "#A4");
133                         }
134
135                         // shell
136                         process.StartInfo.UseShellExecute = true;
137                         try {
138                                 process.Start ();
139                                 Assert.Fail ("#B1");
140                         } catch (InvalidOperationException ex) {
141                                 // Cannot start process because a file name has
142                                 // not been provided
143                                 Assert.AreEqual (typeof (InvalidOperationException), ex.GetType (), "#B2");
144                                 Assert.IsNull (ex.InnerException, "#B3");
145                                 Assert.IsNotNull (ex.Message, "#B4");
146                         }
147                 }
148
149                 [Test] // Start ()
150                 public void Start1_FileName_InvalidPathCharacters ()
151                 {
152                         if (RunningOnUnix)
153                                 // on unix, all characters are allowed
154                                 Assert.Ignore ("Running on Unix.");
155
156                         string systemDir = Environment.GetFolderPath (Environment.SpecialFolder.System);
157                         string exe = "\"" + Path.Combine (systemDir, "calc.exe") + "\"";
158
159                         Process process = new Process ();
160                         process.StartInfo = new ProcessStartInfo (exe);
161
162                         // no shell
163                         process.StartInfo.UseShellExecute = false;
164                         Assert.IsTrue (process.Start ());
165                         process.Kill ();
166
167                         // shell
168                         process.StartInfo.UseShellExecute = true;
169                         Assert.IsTrue (process.Start ());
170                         process.Kill ();
171                 }
172
173                 [Test] // Start ()
174                 public void Start1_FileName_NotFound ()
175                 {
176                         Process process = new Process ();
177                         string exe = RunningOnUnix ? exe = "/usr/bin/shouldnoteverexist"
178                                 : @"c:\shouldnoteverexist.exe";
179
180                         // absolute path, no shell
181                         process.StartInfo = new ProcessStartInfo (exe);
182                         process.StartInfo.UseShellExecute = false;
183                         try {
184                                 process.Start ();
185                                 Assert.Fail ("#A1");
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");
193                         }
194
195                         // relative path, no shell
196                         process.StartInfo.FileName = "shouldnoteverexist.exe";
197                         process.StartInfo.UseShellExecute = false;
198                         try {
199                                 process.Start ();
200                                 Assert.Fail ("#B1");
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");
208                         }
209
210                         if (RunningOnUnix)
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 " +
214                                         "if this fails.");
215
216                         // absolute path, shell
217                         process.StartInfo.FileName = exe;
218                         process.StartInfo.UseShellExecute = true;
219                         try {
220                                 process.Start ();
221                                 Assert.Fail ("#C1");
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");
229                         }
230
231                         // relative path, shell
232                         process.StartInfo.FileName = "shouldnoteverexist.exe";
233                         process.StartInfo.UseShellExecute = true;
234                         try {
235                                 process.Start ();
236                                 Assert.Fail ("#D1");
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");
244                         }
245                 }
246
247                 [Test] // Start ()
248                 public void Start1_FileName_Null ()
249                 {
250                         Process process = new Process ();
251                         process.StartInfo = new ProcessStartInfo ((string) null);
252
253                         // no shell
254                         process.StartInfo.UseShellExecute = false;
255                         try {
256                                 process.Start ();
257                                 Assert.Fail ("#A1");
258                         } catch (InvalidOperationException ex) {
259                                 // Cannot start process because a file name has
260                                 // not been provided
261                                 Assert.AreEqual (typeof (InvalidOperationException), ex.GetType (), "#A2");
262                                 Assert.IsNull (ex.InnerException, "#A3");
263                                 Assert.IsNotNull (ex.Message, "#A4");
264                         }
265
266                         // shell
267                         process.StartInfo.UseShellExecute = true;
268                         try {
269                                 process.Start ();
270                                 Assert.Fail ("#B1");
271                         } catch (InvalidOperationException ex) {
272                                 // Cannot start process because a file name has
273                                 // not been provided
274                                 Assert.AreEqual (typeof (InvalidOperationException), ex.GetType (), "#B2");
275                                 Assert.IsNull (ex.InnerException, "#B3");
276                                 Assert.IsNotNull (ex.Message, "#B4");
277                         }
278                 }
279
280                 [Test] // Start ()
281                 public void Start1_FileName_Whitespace ()
282                 {
283                         Process process = new Process ();
284                         process.StartInfo = new ProcessStartInfo (" ");
285                         process.StartInfo.UseShellExecute = false;
286                         try {
287                                 process.Start ();
288                                 Assert.Fail ("#1");
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");
298                         }
299                 }
300
301                 [Test] // Start (ProcessStartInfo)
302                 public void Start2_FileName_Empty ()
303                 {
304                         ProcessStartInfo startInfo = new ProcessStartInfo (string.Empty);
305
306                         // no shell
307                         startInfo.UseShellExecute = false;
308                         try {
309                                 Process.Start (startInfo);
310                                 Assert.Fail ("#A1");
311                         } catch (InvalidOperationException ex) {
312                                 // Cannot start process because a file name has
313                                 // not been provided
314                                 Assert.AreEqual (typeof (InvalidOperationException), ex.GetType (), "#A2");
315                                 Assert.IsNull (ex.InnerException, "#A3");
316                                 Assert.IsNotNull (ex.Message, "#A4");
317                         }
318
319                         // shell
320                         startInfo.UseShellExecute = true;
321                         try {
322                                 Process.Start (startInfo);
323                                 Assert.Fail ("#B1");
324                         } catch (InvalidOperationException ex) {
325                                 // Cannot start process because a file name has
326                                 // not been provided
327                                 Assert.AreEqual (typeof (InvalidOperationException), ex.GetType (), "#B2");
328                                 Assert.IsNull (ex.InnerException, "#B3");
329                                 Assert.IsNotNull (ex.Message, "#B4");
330                         }
331                 }
332
333                 [Test] // Start (ProcessStartInfo)
334                 public void Start2_FileName_NotFound ()
335                 {
336                         ProcessStartInfo startInfo = new ProcessStartInfo ();
337                         string exe = RunningOnUnix ? exe = "/usr/bin/shouldnoteverexist"
338                                 : @"c:\shouldnoteverexist.exe";
339
340                         // absolute path, no shell
341                         startInfo.FileName = exe;
342                         startInfo.UseShellExecute = false;
343                         try {
344                                 Process.Start (startInfo);
345                                 Assert.Fail ("#A1");
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");
353                         }
354
355                         // relative path, no shell
356                         startInfo.FileName = "shouldnoteverexist.exe";
357                         startInfo.UseShellExecute = false;
358                         try {
359                                 Process.Start (startInfo);
360                                 Assert.Fail ("#B1");
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");
368                         }
369
370                         if (RunningOnUnix)
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 " +
374                                         "if this fails.");
375
376                         // absolute path, shell
377                         startInfo.FileName = exe;
378                         startInfo.UseShellExecute = true;
379                         try {
380                                 Process.Start (startInfo);
381                                 Assert.Fail ("#C1");
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");
389                         }
390
391                         // relative path, shell
392                         startInfo.FileName = "shouldnoteverexist.exe";
393                         startInfo.UseShellExecute = true;
394                         try {
395                                 Process.Start (startInfo);
396                                 Assert.Fail ("#D1");
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");
404                         }
405                 }
406
407                 [Test] // Start (ProcessStartInfo)
408                 public void Start2_FileName_Null ()
409                 {
410                         ProcessStartInfo startInfo = new ProcessStartInfo ((string) null);
411
412                         // no shell
413                         startInfo.UseShellExecute = false;
414                         try {
415                                 Process.Start (startInfo);
416                                 Assert.Fail ("#A1");
417                         } catch (InvalidOperationException ex) {
418                                 // Cannot start process because a file name has
419                                 // not been provided
420                                 Assert.AreEqual (typeof (InvalidOperationException), ex.GetType (), "#A2");
421                                 Assert.IsNull (ex.InnerException, "#A3");
422                                 Assert.IsNotNull (ex.Message, "#A4");
423                         }
424
425                         // shell
426                         startInfo.UseShellExecute = true;
427                         try {
428                                 Process.Start (startInfo);
429                                 Assert.Fail ("#B1");
430                         } catch (InvalidOperationException ex) {
431                                 // Cannot start process because a file name has
432                                 // not been provided
433                                 Assert.AreEqual (typeof (InvalidOperationException), ex.GetType (), "#B2");
434                                 Assert.IsNull (ex.InnerException, "#B3");
435                                 Assert.IsNotNull (ex.Message, "#B4");
436                         }
437                 }
438
439                 [Test] // Start (ProcessStartInfo)
440                 public void Start2_FileName_Whitespace ()
441                 {
442                         ProcessStartInfo startInfo = new ProcessStartInfo (" ");
443                         startInfo.UseShellExecute = false;
444                         try {
445                                 Process.Start (startInfo);
446                                 Assert.Fail ("#1");
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");
456                         }
457                 }
458
459                 [Test] // Start (ProcessStartInfo)
460                 public void Start2_StartInfo_Null ()
461                 {
462                         try {
463                                 Process.Start ((ProcessStartInfo) null);
464                                 Assert.Fail ("#1");
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");
471                         }
472                 }
473
474                 [Test] // Start (string)
475                 public void Start3_FileName_Empty ()
476                 {
477                         try {
478                                 Process.Start (string.Empty);
479                                 Assert.Fail ("#1");
480                         } catch (InvalidOperationException ex) {
481                                 // Cannot start process because a file name has
482                                 // not been provided
483                                 Assert.AreEqual (typeof (InvalidOperationException), ex.GetType (), "#2");
484                                 Assert.IsNull (ex.InnerException, "#3");
485                                 Assert.IsNotNull (ex.Message, "#4");
486                         }
487                 }
488
489                 [Test] // Start (string)
490                 public void Start3_FileName_NotFound ()
491                 {
492                         if (RunningOnUnix)
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 " +
496                                         "if this fails.");
497
498                         string exe = @"c:\shouldnoteverexist.exe";
499
500                         // absolute path, no shell
501                         try {
502                                 Process.Start (exe);
503                                 Assert.Fail ("#A1");
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");
511                         }
512
513                         // relative path, no shell
514                         try {
515                                 Process.Start ("shouldnoteverexist.exe");
516                                 Assert.Fail ("#B1");
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");
524                         }
525                 }
526
527                 [Test] // Start (string)
528                 public void Start3_FileName_Null ()
529                 {
530                         try {
531                                 Process.Start ((string) null);
532                                 Assert.Fail ("#1");
533                         } catch (InvalidOperationException ex) {
534                                 // Cannot start process because a file name has
535                                 // not been provided
536                                 Assert.AreEqual (typeof (InvalidOperationException), ex.GetType (), "#2");
537                                 Assert.IsNull (ex.InnerException, "#3");
538                                 Assert.IsNotNull (ex.Message, "#4");
539                         }
540                 }
541
542                 [Test] // Start (string, string)
543                 public void Start4_Arguments_Null ()
544                 {
545                         if (RunningOnUnix)
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 " +
549                                         "if this fails.");
550
551                         string exe = @"c:\shouldnoteverexist.exe";
552
553                         try {
554                                 Process.Start ("whatever.exe", (string) null);
555                                 Assert.Fail ("#1");
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");
563                         }
564                 }
565
566                 [Test] // Start (string, string)
567                 public void Start4_FileName_Empty ()
568                 {
569                         try {
570                                 Process.Start (string.Empty, string.Empty);
571                                 Assert.Fail ("#1");
572                         } catch (InvalidOperationException ex) {
573                                 // Cannot start process because a file name has
574                                 // not been provided
575                                 Assert.AreEqual (typeof (InvalidOperationException), ex.GetType (), "#2");
576                                 Assert.IsNull (ex.InnerException, "#3");
577                                 Assert.IsNotNull (ex.Message, "#4");
578                         }
579                 }
580
581                 [Test] // Start (string, string)
582                 public void Start4_FileName_NotFound ()
583                 {
584                         if (RunningOnUnix)
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 " +
588                                         "if this fails.");
589
590                         string exe = @"c:\shouldnoteverexist.exe";
591
592                         // absolute path, no shell
593                         try {
594                                 Process.Start (exe, string.Empty);
595                                 Assert.Fail ("#A1");
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");
603                         }
604
605                         // relative path, no shell
606                         try {
607                                 Process.Start ("shouldnoteverexist.exe", string.Empty);
608                                 Assert.Fail ("#B1");
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");
616                         }
617                 }
618
619                 [Test]
620                 public void Start_UseShellExecuteWithEmptyUserName ()
621                 {
622                         if (RunningOnUnix)
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 " +
626                                         "if this fails.");
627
628                         string exe = @"c:\shouldnoteverexist.exe";
629
630                         try {
631                                 Process p = new Process ();
632                                 p.StartInfo.FileName = exe;
633                                 p.StartInfo.UseShellExecute = true;
634                                 p.StartInfo.UserName = "";
635                                 p.Start ();
636                                 Assert.Fail ("#1");
637                         } catch (InvalidOperationException) {
638                                 Assert.Fail ("#2");
639                         } catch (Win32Exception) {
640                         }
641
642                         try {
643                                 Process p = new Process ();
644                                 p.StartInfo.FileName = exe;
645                                 p.StartInfo.UseShellExecute = true;
646                                 p.StartInfo.UserName = null;
647                                 p.Start ();
648                                 Assert.Fail ("#3");                             
649                         } catch (InvalidOperationException) {
650                                 Assert.Fail ("#4");
651                         } catch (Win32Exception) {
652                         }
653                 }
654                 
655                 [Test] // Start (string, string)
656                 public void Start4_FileName_Null ()
657                 {
658                         try {
659                                 Process.Start ((string) null, string.Empty);
660                                 Assert.Fail ("#1");
661                         } catch (InvalidOperationException ex) {
662                                 // Cannot start process because a file name has
663                                 // not been provided
664                                 Assert.AreEqual (typeof (InvalidOperationException), ex.GetType (), "#2");
665                                 Assert.IsNull (ex.InnerException, "#3");
666                                 Assert.IsNotNull (ex.Message, "#4");
667                         }
668                 }
669
670                 [Test]
671                 public void StartInfo ()
672                 {
673                         ProcessStartInfo startInfo = new ProcessStartInfo ();
674
675                         Process p = new Process ();
676                         Assert.IsNotNull (p.StartInfo, "#A1");
677                         p.StartInfo = startInfo;
678                         Assert.AreSame (startInfo, p.StartInfo, "#A2");
679                 }
680
681                 [Test]
682                 public void StartInfo_Null ()
683                 {
684                         Process p = new Process ();
685                         try {
686                                 p.StartInfo = null;
687                                 Assert.Fail ("#1");
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");
694                         }
695                 }
696
697                 [Test]
698                 [NUnit.Framework.Category ("NotDotNet")]
699                 [NUnit.Framework.Category ("MobileNotWorking")]
700                 public void TestRedirectedOutputIsAsync ()
701                 {
702                         // Test requires cygwin, so we just bail out for now.
703                         if (Path.DirectorySeparatorChar == '\\')
704                                 Assert.Ignore ("Test requires cygwin.");
705                         
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;
710                         p.Start ();
711
712                         Stream stdout = p.StandardOutput.BaseStream;
713
714                         byte [] buffer = new byte [200];
715
716                         // start async Read operation
717                         DateTime start = DateTime.Now;
718                         IAsyncResult ar = stdout.BeginRead (buffer, 0, buffer.Length,
719                                                             new AsyncCallback (Read), stdout);
720
721                         Assert.IsTrue ((DateTime.Now - start).TotalMilliseconds < 1000, "#01 BeginRead was not async");
722                         p.WaitForExit ();
723                         Assert.AreEqual (0, p.ExitCode, "#02 script failure");
724
725                         /*
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");
730                         */
731                 }
732                 
733                 void Read (IAsyncResult ar)
734                 {
735                         Stream stm = (Stream) ar.AsyncState;
736                         bytesRead = stm.EndRead (ar);
737                 }
738
739                 public int bytesRead = -1;
740
741                 [Test]
742                 [NUnit.Framework.Category ("MobileNotWorking")]
743                 // This was for bug #459450
744                 public void TestEventRaising ()
745                 {
746                         EventWaitHandle errorClosed = new ManualResetEvent(false);
747                         EventWaitHandle outClosed = new ManualResetEvent(false);
748                         EventWaitHandle exited = new ManualResetEvent(false);
749
750                         Process p = new Process();
751                         
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) {
759                                         outClosed.Set();
760                                 }
761                         };
762                         
763                         p.ErrorDataReceived += (object sender, DataReceivedEventArgs e) => {
764                                 if (e.Data == null) {
765                                         errorClosed.Set();
766                                 }
767                         };
768                         
769                         p.Exited += (object sender, EventArgs e) => {
770                                 exited.Set ();
771                         };
772                         
773                         p.EnableRaisingEvents = true;
774
775                         p.Start();
776
777                         p.BeginErrorReadLine();
778                         p.BeginOutputReadLine();
779
780                         Console.WriteLine("started, waiting for handles");
781                         bool r = WaitHandle.WaitAll(new WaitHandle[] { errorClosed, outClosed, exited }, 10000, false);
782
783                         Assert.AreEqual (true, r, "Null Argument Events Raised");
784                 }
785
786                 [Test]
787                 [NUnit.Framework.Category ("MobileNotWorking")]
788                 public void TestEnableEventsAfterExitedEvent ()
789                 {
790                         Process p = new Process ();
791                         
792                         p.StartInfo = GetCrossPlatformStartInfo ();
793                         p.StartInfo.UseShellExecute = false;
794                         p.StartInfo.RedirectStandardOutput = true;
795                         p.StartInfo.RedirectStandardError = true;
796
797                         var exitedCalledCounter = 0;
798                         var exited = new ManualResetEventSlim ();
799                         p.Exited += (object sender, EventArgs e) => {
800                                 exitedCalledCounter++;
801                                 Assert.IsTrue (p.HasExited);
802                                 exited.Set ();
803                         };
804
805                         p.EnableRaisingEvents = true;
806
807                         p.Start ();
808                         p.BeginErrorReadLine ();
809                         p.BeginOutputReadLine ();
810                         p.WaitForExit ();
811
812                         exited.Wait (10000);
813                         Assert.AreEqual (1, exitedCalledCounter);
814                         Thread.Sleep (50);
815                         Assert.AreEqual (1, exitedCalledCounter);
816                 }
817
818                 [Test]
819                 [NUnit.Framework.Category ("MobileNotWorking")]
820                 public void TestEnableEventsBeforeExitedEvent ()
821                 {
822                         Process p = new Process ();
823                         
824                         p.StartInfo = GetCrossPlatformStartInfo ();
825                         p.StartInfo.UseShellExecute = false;
826                         p.StartInfo.RedirectStandardOutput = true;
827                         p.StartInfo.RedirectStandardError = true;
828
829                         p.EnableRaisingEvents = true;
830
831                         var exitedCalledCounter = 0;
832                         var exited = new ManualResetEventSlim ();
833                         p.Exited += (object sender, EventArgs e) => {
834                                 exitedCalledCounter++;
835                                 Assert.IsTrue (p.HasExited);
836                                 exited.Set ();
837                         };
838
839                         p.Start ();
840                         p.BeginErrorReadLine ();
841                         p.BeginOutputReadLine ();
842                         p.WaitForExit ();
843
844                         Assert.IsTrue (exited.Wait (10000));
845                         Assert.AreEqual (1, exitedCalledCounter);
846                         Thread.Sleep (50);
847                         Assert.AreEqual (1, exitedCalledCounter);
848                 }
849
850                 [Test]
851                 [NUnit.Framework.Category ("MobileNotWorking")]
852                 public void TestDisableEventsBeforeExitedEvent ()
853                 {
854                         Process p = new Process ();
855                         
856                         p.StartInfo = GetCrossPlatformStartInfo ();
857                         p.StartInfo.UseShellExecute = false;
858                         p.StartInfo.RedirectStandardOutput = true;
859                         p.StartInfo.RedirectStandardError = true;
860
861                         p.EnableRaisingEvents = false;
862
863                         ManualResetEvent mre = new ManualResetEvent (false);
864                         p.Exited += (object sender, EventArgs e) => {
865                                 mre.Set ();
866                         };
867
868                         p.Start ();
869                         p.BeginErrorReadLine ();
870                         p.BeginOutputReadLine ();
871                         p.WaitForExit ();
872
873                         Assert.IsFalse (mre.WaitOne (1000));
874                 }
875
876                 ProcessStartInfo GetCrossPlatformStartInfo ()
877                 {
878                         if (RunningOnUnix) {
879                                 string path;
880 #if MONODROID
881                                 path = "/system/bin/ls";
882 #else
883                                 path = "/bin/ls";
884 #endif
885                                 return new ProcessStartInfo (path, "/");
886                         } else
887                                 return new ProcessStartInfo ("help", "");
888                 }
889
890                 ProcessStartInfo GetEchoCrossPlatformStartInfo ()
891                 {
892                         if (RunningOnUnix) {
893                                 string path;
894 #if MONODROID
895                                 path = "/system/bin/cat";
896 #else
897                                 path = "/bin/cat";
898 #endif
899                                 return new ProcessStartInfo (path);
900                         } else {
901                                 var psi = new ProcessStartInfo ("findstr");
902                                 psi.Arguments = "\"^\"";
903                                 return psi;
904                         }
905                 }
906 #endif // MONO_FEATURE_PROCESS_START
907
908                 [Test]
909                 public void ProcessName_NotStarted ()
910                 {
911                         Process p = new Process ();
912                         Exception e = null;
913                         try {
914                                 String.IsNullOrEmpty (p.ProcessName);
915                         } catch (Exception ex) {
916                                 e = ex;
917                         }
918                         
919                         Assert.IsNotNull (e, "ProcessName should raise if process was not started");
920                         
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);
924                         
925                         Assert.IsNull (e.InnerException, "IOE inner exception should be null");
926                 }
927                 
928 #if MONO_FEATURE_PROCESS_START
929                 [Test]
930                 [NUnit.Framework.Category ("MobileNotWorking")]
931                 public void ProcessName_AfterExit ()
932                 {
933                         Process p = new Process ();
934                         p.StartInfo = GetCrossPlatformStartInfo ();
935                         p.StartInfo.UseShellExecute = false;
936                         p.StartInfo.RedirectStandardOutput = true;
937                         p.StartInfo.RedirectStandardError = true;
938                         p.Start ();
939                         p.BeginErrorReadLine();
940                         p.BeginOutputReadLine();
941                         p.WaitForExit ();
942                         String.IsNullOrEmpty (p.ExitCode + "");
943                         
944                         Exception e = null;
945                         try {
946                                 String.IsNullOrEmpty (p.ProcessName);
947                         } catch (Exception ex) {
948                                 e = ex;
949                         }
950                         
951                         Assert.IsNotNull (e, "ProcessName should raise if process was finished");
952                         
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);
956                         
957                         Assert.IsNull (e.InnerException, "IOE inner exception should be null");
958                 }
959 #endif // MONO_FEATURE_PROCESS_START
960
961                 [Test]
962                 public void Handle_ThrowsOnNotStarted ()
963                 {
964                         Process p = new Process ();
965                         try {
966                                 var x = p.Handle;
967                                 Assert.Fail ("Handle should throw for unstated procs, but returned " + x);
968                         } catch (InvalidOperationException) {
969                         }
970                 }
971
972                 [Test]
973                 public void HasExitedCurrent () {
974                         Assert.IsFalse (Process.GetCurrentProcess ().HasExited);
975                 }
976
977 #if MONO_FEATURE_PROCESS_START
978                 [Test]
979                 [NUnit.Framework.Category ("MobileNotWorking")]
980                 public void DisposeWithDisposedStreams ()
981                 {
982                         var psi = GetCrossPlatformStartInfo ();
983                         psi.RedirectStandardInput = true;
984                         psi.RedirectStandardOutput = true;
985                         psi.UseShellExecute = false;
986
987                         var p = Process.Start (psi);
988                         p.StandardInput.BaseStream.Dispose ();
989                         p.StandardOutput.BaseStream.Dispose ();
990                         p.Dispose ();
991                 }
992
993                 [Test]
994                 [NUnit.Framework.Category ("MobileNotWorking")]
995                 public void StandardInputWrite ()
996                 {
997                         var psi = GetEchoCrossPlatformStartInfo ();
998                         psi.RedirectStandardInput = true;
999                         psi.RedirectStandardOutput = true;
1000                         psi.UseShellExecute = false;
1001
1002                         using (var p = Process.Start (psi)) {
1003                                 // drain stdout
1004                                 p.OutputDataReceived += (s, e) => {};
1005                                 p.BeginOutputReadLine ();
1006
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 ();
1011                                 }
1012
1013                                 p.StandardInput.Close ();
1014
1015                                 p.WaitForExit ();
1016                         }
1017                 }
1018 #endif // MONO_FEATURE_PROCESS_START
1019
1020                 [Test]
1021                 public void Modules () {
1022                         var modules = Process.GetCurrentProcess ().Modules;
1023                         foreach (var a in AppDomain.CurrentDomain.GetAssemblies ()) {
1024                                 var found = false;
1025                                 var name = a.GetName ();
1026
1027                                 StringBuilder sb = new StringBuilder ();
1028                                 sb.AppendFormat ("Could not found: {0} {1}\n", name.Name, name.Version);
1029                                 sb.AppendLine ("Looked in modules:");
1030
1031                                 foreach (var o in modules) {
1032                                         var m = (ProcessModule) o;
1033
1034                                         sb.AppendFormat ("   {0} {1}.{2}.{3}\n", m.FileName.ToString (),
1035                                                         m.FileVersionInfo.FileMajorPart,
1036                                                         m.FileVersionInfo.FileMinorPart,
1037                                                         m.FileVersionInfo.FileBuildPart);
1038
1039                                         if (!m.FileName.StartsWith ("[In Memory] " + name.Name))
1040                                                 continue;
1041
1042                                         var fv = m.FileVersionInfo;
1043                                         if (fv.FileBuildPart != name.Version.Build ||
1044                                                 fv.FileMinorPart != name.Version.Minor ||
1045                                                 fv.FileMajorPart != name.Version.Major)
1046                                                 continue;
1047
1048                                         found = true;
1049                                 }
1050
1051                                 Assert.IsTrue (found, sb.ToString ());
1052                         }
1053                 }
1054
1055 #if MONO_FEATURE_PROCESS_START
1056                 [Test]
1057                 [NUnit.Framework.Category ("MobileNotWorking")]
1058                 [ExpectedException (typeof (InvalidOperationException))]
1059                 public void TestDoubleBeginOutputReadLine ()
1060                 {
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;
1066
1067                                 p.Start ();
1068
1069                                 p.BeginOutputReadLine ();
1070                                 p.BeginOutputReadLine ();
1071
1072                                 Assert.Fail ();
1073                         }
1074                 }
1075
1076                 [Test]
1077                 [NUnit.Framework.Category ("MobileNotWorking")]
1078                 [ExpectedException (typeof (InvalidOperationException))]
1079                 public void TestDoubleBeginErrorReadLine ()
1080                 {
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;
1086
1087                                 p.Start ();
1088
1089                                 p.BeginErrorReadLine ();
1090                                 p.BeginErrorReadLine ();
1091
1092                                 Assert.Fail ();
1093                         }
1094                 }
1095
1096                 [Test]
1097                 [NUnit.Framework.Category ("MobileNotWorking")]
1098                 public void TestExitedRaisedTooSoon ()
1099                 {
1100                         if (!RunningOnUnix)
1101                                 Assert.Ignore ("using sleep command, only available on unix");
1102
1103                         int sleeptime = 5;
1104
1105                         using (Process p = Process.Start("sleep", sleeptime.ToString ())) {
1106                                 ManualResetEvent mre = new ManualResetEvent (false);
1107
1108                                 p.EnableRaisingEvents = true;
1109                                 p.Exited += (sender, e) => {
1110                                         mre.Set ();
1111                                 };
1112
1113                                 Assert.IsFalse (mre.WaitOne ((sleeptime - 2) * 1000), "Exited triggered before the process returned");
1114                         }
1115                 }
1116 #endif // MONO_FEATURE_PROCESS_START
1117
1118                 [Test]
1119                 [NUnit.Framework.Category ("MobileNotWorking")]
1120                 public void GetProcessesByName()
1121                 {
1122                         // This should return Process[0] or a Process[] with all the "foo" programs running
1123                         Process.GetProcessesByName ("foo");
1124                 }
1125
1126                 [Test]
1127                 [NUnit.Framework.Category ("NotWorking")] //Getting the name of init works fine on Android and Linux, but fails on OSX, SELinux and iOS
1128                 public void HigherPrivilegeProcessName ()
1129                 {
1130                         if (!RunningOnUnix)
1131                                 Assert.Ignore ("accessing pid 1, only available on unix");
1132
1133                         string v = Process.GetProcessById (1).ProcessName;
1134                 }
1135
1136                 [Test]
1137                 [NUnit.Framework.Category ("MobileNotWorking")]
1138                 public void NonChildProcessWaitForExit ()
1139                 {
1140                         if (!RunningOnUnix)
1141                                 Assert.Ignore ("accessing parent pid, only available on unix");
1142
1143                         using (Process process = Process.GetProcessById (getppid ()))
1144                         using (ManualResetEvent mre = new ManualResetEvent (false))
1145                         {
1146                                 Assert.IsFalse (process.WaitForExit (10), "#1");
1147                                 Assert.IsFalse (process.HasExited, "#2");
1148                                 Assert.Throws<InvalidOperationException>(delegate { int exitCode = process.ExitCode; }, "#3");
1149
1150                                 process.Exited += (s, e) => mre.Set ();
1151                                 process.EnableRaisingEvents = true;
1152                                 Assert.IsFalse (mre.WaitOne (100), "#4");
1153
1154                                 Assert.IsFalse (process.WaitForExit (10), "#5");
1155                                 Assert.IsFalse (process.HasExited, "#6");
1156                                 Assert.Throws<InvalidOperationException>(delegate { int exitCode = process.ExitCode; }, "#7");
1157                         }
1158                 }
1159
1160                 [Test]
1161                 [NUnit.Framework.Category ("MobileNotWorking")]
1162                 public void NonChildProcessName ()
1163                 {
1164                         if (!RunningOnUnix)
1165                                 Assert.Ignore ("accessing parent pid, only available on unix");
1166
1167                         using (Process process = Process.GetProcessById (getppid ()))
1168                         {
1169                                 string pname = process.ProcessName;
1170                                 Assert.IsNotNull (pname, "#1");
1171                                 AssertHelper.IsNotEmpty (pname, "#2");
1172                         }
1173                 }
1174
1175                 [Test]
1176                 [NUnit.Framework.Category ("MobileNotWorking")]
1177                 public void NonChildProcessId ()
1178                 {
1179                         if (!RunningOnUnix)
1180                                 Assert.Ignore ("accessing parent pid, only available on unix");
1181
1182                         int ppid;
1183                         using (Process process = Process.GetProcessById (ppid = getppid ()))
1184                         {
1185                                 int pid = process.Id;
1186                                 Assert.AreEqual (ppid, pid, "#1");
1187                                 AssertHelper.Greater (pid, 0, "#2");
1188                         }
1189                 }
1190
1191                 [DllImport ("libc")]
1192                 static extern int getppid();
1193         }
1194 }