[System] Process.WaitForExit now triggers event Exited.
[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
18 using NUnit.Framework;
19
20 namespace MonoTests.System.Diagnostics
21 {
22         [TestFixture]
23         public class ProcessTest
24         {
25                 [Test]
26                 public void GetProcessById_MachineName_Null ()
27                 {
28                         try {
29                                 Process.GetProcessById (1, (string) null);
30                                 Assert.Fail ("#1");
31                         } catch (ArgumentNullException ex) {
32                                 Assert.AreEqual (typeof (ArgumentNullException), ex.GetType (), "#2");
33                                 Assert.IsNotNull (ex.Message, "#3");
34                                 Assert.IsNotNull (ex.ParamName, "#4");
35                                 Assert.AreEqual ("machineName", ex.ParamName, "#5");
36                                 Assert.IsNull (ex.InnerException, "#6");
37                         }
38                 }
39
40                 [Test]
41                 public void GetProcesses_MachineName_Null ()
42                 {
43                         try {
44                                 Process.GetProcesses ((string) null);
45                                 Assert.Fail ("#1");
46                         } catch (ArgumentNullException ex) {
47                                 Assert.AreEqual (typeof (ArgumentNullException), ex.GetType (), "#2");
48                                 Assert.IsNotNull (ex.Message, "#3");
49                                 Assert.IsNotNull (ex.ParamName, "#4");
50                                 Assert.AreEqual ("machineName", ex.ParamName, "#5");
51                                 Assert.IsNull (ex.InnerException, "#6");
52                         }
53                 }
54
55                 [Test]
56                 public void PriorityClass_NotStarted ()
57                 {
58                         Process process = new Process ();
59                         try {
60                                 process.PriorityClass = ProcessPriorityClass.Normal;
61                                 Assert.Fail ("#A1");
62                         } catch (InvalidOperationException ex) {
63                                 // No process is associated with this object
64                                 Assert.AreEqual (typeof (InvalidOperationException), ex.GetType (), "#A2");
65                                 Assert.IsNull (ex.InnerException, "#A3");
66                                 Assert.IsNotNull (ex.Message, "#A4");
67                         }
68
69                         try {
70                                 Assert.Fail ("#B1:" + process.PriorityClass);
71                         } catch (InvalidOperationException ex) {
72                                 // No process is associated with this object
73                                 Assert.AreEqual (typeof (InvalidOperationException), ex.GetType (), "#B2");
74                                 Assert.IsNull (ex.InnerException, "#B3");
75                                 Assert.IsNotNull (ex.Message, "#B4");
76                         }
77                 }
78
79                 [Test]
80                 public void PriorityClass_Invalid ()
81                 {
82                         Process process = new Process ();
83                         try {
84                                 process.PriorityClass = (ProcessPriorityClass) 666;
85                                 Assert.Fail ("#1");
86                         } catch (InvalidEnumArgumentException ex) {
87                                 Assert.AreEqual (typeof (InvalidEnumArgumentException), ex.GetType (), "#2");
88                                 Assert.IsNull (ex.InnerException, "#3");
89                                 Assert.IsNotNull (ex.Message, "#4");
90                                 Assert.IsTrue (ex.Message.IndexOf ("666") != -1, "#5");
91                                 Assert.IsTrue (ex.Message.IndexOf (typeof (ProcessPriorityClass).Name) != -1, "#6");
92                                 Assert.IsNotNull (ex.ParamName, "#7");
93                                 Assert.AreEqual ("value", ex.ParamName, "#8");
94                         }
95                 }
96
97                 [Test] // Start ()
98                 public void Start1_FileName_Empty ()
99                 {
100                         Process process = new Process ();
101                         process.StartInfo = new ProcessStartInfo (string.Empty);
102
103                         // no shell
104                         process.StartInfo.UseShellExecute = false;
105                         try {
106                                 process.Start ();
107                                 Assert.Fail ("#A1");
108                         } catch (InvalidOperationException ex) {
109                                 // Cannot start process because a file name has
110                                 // not been provided
111                                 Assert.AreEqual (typeof (InvalidOperationException), ex.GetType (), "#A2");
112                                 Assert.IsNull (ex.InnerException, "#A3");
113                                 Assert.IsNotNull (ex.Message, "#A4");
114                         }
115
116                         // shell
117                         process.StartInfo.UseShellExecute = true;
118                         try {
119                                 process.Start ();
120                                 Assert.Fail ("#B1");
121                         } catch (InvalidOperationException ex) {
122                                 // Cannot start process because a file name has
123                                 // not been provided
124                                 Assert.AreEqual (typeof (InvalidOperationException), ex.GetType (), "#B2");
125                                 Assert.IsNull (ex.InnerException, "#B3");
126                                 Assert.IsNotNull (ex.Message, "#B4");
127                         }
128                 }
129
130                 [Test] // Start ()
131                 public void Start1_FileName_InvalidPathCharacters ()
132                 {
133                         if (RunningOnUnix)
134                                 // on unix, all characters are allowed
135                                 Assert.Ignore ("Running on Unix.");
136
137                         string systemDir = Environment.GetFolderPath (Environment.SpecialFolder.System);
138                         string exe = "\"" + Path.Combine (systemDir, "calc.exe") + "\"";
139
140                         Process process = new Process ();
141                         process.StartInfo = new ProcessStartInfo (exe);
142
143                         // no shell
144                         process.StartInfo.UseShellExecute = false;
145                         Assert.IsTrue (process.Start ());
146                         process.Kill ();
147
148                         // shell
149                         process.StartInfo.UseShellExecute = true;
150                         Assert.IsTrue (process.Start ());
151                         process.Kill ();
152                 }
153
154                 [Test] // Start ()
155                 public void Start1_FileName_NotFound ()
156                 {
157                         Process process = new Process ();
158                         string exe = RunningOnUnix ? exe = "/usr/bin/shouldnoteverexist"
159                                 : @"c:\shouldnoteverexist.exe";
160
161                         // absolute path, no shell
162                         process.StartInfo = new ProcessStartInfo (exe);
163                         process.StartInfo.UseShellExecute = false;
164                         try {
165                                 process.Start ();
166                                 Assert.Fail ("#A1");
167                         } catch (Win32Exception ex) {
168                                 // The system cannot find the file specified
169                                 Assert.AreEqual (typeof (Win32Exception), ex.GetType (), "#A2");
170                                 Assert.AreEqual (-2147467259, ex.ErrorCode, "#A3");
171                                 Assert.IsNull (ex.InnerException, "#A4");
172                                 Assert.IsNotNull (ex.Message, "#A5");
173                                 Assert.AreEqual (2, ex.NativeErrorCode, "#A6");
174                         }
175
176                         // relative path, no shell
177                         process.StartInfo.FileName = "shouldnoteverexist.exe";
178                         process.StartInfo.UseShellExecute = false;
179                         try {
180                                 process.Start ();
181                                 Assert.Fail ("#B1");
182                         } catch (Win32Exception ex) {
183                                 // The system cannot find the file specified
184                                 Assert.AreEqual (typeof (Win32Exception), ex.GetType (), "#B2");
185                                 Assert.AreEqual (-2147467259, ex.ErrorCode, "#B3");
186                                 Assert.IsNull (ex.InnerException, "#B4");
187                                 Assert.IsNotNull (ex.Message, "#B5");
188                                 Assert.AreEqual (2, ex.NativeErrorCode, "#B6");
189                         }
190
191                         if (RunningOnUnix)
192                                 Assert.Ignore ("On Unix and Mac OS X, we try " +
193                                         "to open any file (using xdg-open, ...)" +
194                                         " and we do not report an exception " +
195                                         "if this fails.");
196
197                         // absolute path, shell
198                         process.StartInfo.FileName = exe;
199                         process.StartInfo.UseShellExecute = true;
200                         try {
201                                 process.Start ();
202                                 Assert.Fail ("#C1");
203                         } catch (Win32Exception ex) {
204                                 // The system cannot find the file specified
205                                 Assert.AreEqual (typeof (Win32Exception), ex.GetType (), "#C2");
206                                 Assert.AreEqual (-2147467259, ex.ErrorCode, "#C3");
207                                 Assert.IsNull (ex.InnerException, "#C4");
208                                 Assert.IsNotNull (ex.Message, "#C5");
209                                 Assert.AreEqual (2, ex.NativeErrorCode, "#C6");
210                         }
211
212                         // relative path, shell
213                         process.StartInfo.FileName = "shouldnoteverexist.exe";
214                         process.StartInfo.UseShellExecute = true;
215                         try {
216                                 process.Start ();
217                                 Assert.Fail ("#D1");
218                         } catch (Win32Exception ex) {
219                                 // The system cannot find the file specified
220                                 Assert.AreEqual (typeof (Win32Exception), ex.GetType (), "#D2");
221                                 Assert.AreEqual (-2147467259, ex.ErrorCode, "#D3");
222                                 Assert.IsNull (ex.InnerException, "#D4");
223                                 Assert.IsNotNull (ex.Message, "#D5");
224                                 Assert.AreEqual (2, ex.NativeErrorCode, "#D6");
225                         }
226                 }
227
228                 [Test] // Start ()
229                 public void Start1_FileName_Null ()
230                 {
231                         Process process = new Process ();
232                         process.StartInfo = new ProcessStartInfo ((string) null);
233
234                         // no shell
235                         process.StartInfo.UseShellExecute = false;
236                         try {
237                                 process.Start ();
238                                 Assert.Fail ("#A1");
239                         } catch (InvalidOperationException ex) {
240                                 // Cannot start process because a file name has
241                                 // not been provided
242                                 Assert.AreEqual (typeof (InvalidOperationException), ex.GetType (), "#A2");
243                                 Assert.IsNull (ex.InnerException, "#A3");
244                                 Assert.IsNotNull (ex.Message, "#A4");
245                         }
246
247                         // shell
248                         process.StartInfo.UseShellExecute = true;
249                         try {
250                                 process.Start ();
251                                 Assert.Fail ("#B1");
252                         } catch (InvalidOperationException ex) {
253                                 // Cannot start process because a file name has
254                                 // not been provided
255                                 Assert.AreEqual (typeof (InvalidOperationException), ex.GetType (), "#B2");
256                                 Assert.IsNull (ex.InnerException, "#B3");
257                                 Assert.IsNotNull (ex.Message, "#B4");
258                         }
259                 }
260
261                 [Test] // Start ()
262                 public void Start1_FileName_Whitespace ()
263                 {
264                         Process process = new Process ();
265                         process.StartInfo = new ProcessStartInfo (" ");
266                         process.StartInfo.UseShellExecute = false;
267                         try {
268                                 process.Start ();
269                                 Assert.Fail ("#1");
270                         } catch (Win32Exception ex) {
271                                 // The system cannot find the file specified
272                                 Assert.AreEqual (typeof (Win32Exception), ex.GetType (), "#2");
273                                 Assert.AreEqual (-2147467259, ex.ErrorCode, "#3");
274                                 Assert.IsNull (ex.InnerException, "#4");
275                                 Assert.IsNotNull (ex.Message, "#5");
276                                 Assert.AreEqual (2, ex.NativeErrorCode, "#6");
277                         }
278                 }
279
280                 [Test] // Start (ProcessStartInfo)
281                 public void Start2_FileName_Empty ()
282                 {
283                         ProcessStartInfo startInfo = new ProcessStartInfo (string.Empty);
284
285                         // no shell
286                         startInfo.UseShellExecute = false;
287                         try {
288                                 Process.Start (startInfo);
289                                 Assert.Fail ("#A1");
290                         } catch (InvalidOperationException ex) {
291                                 // Cannot start process because a file name has
292                                 // not been provided
293                                 Assert.AreEqual (typeof (InvalidOperationException), ex.GetType (), "#A2");
294                                 Assert.IsNull (ex.InnerException, "#A3");
295                                 Assert.IsNotNull (ex.Message, "#A4");
296                         }
297
298                         // shell
299                         startInfo.UseShellExecute = true;
300                         try {
301                                 Process.Start (startInfo);
302                                 Assert.Fail ("#B1");
303                         } catch (InvalidOperationException ex) {
304                                 // Cannot start process because a file name has
305                                 // not been provided
306                                 Assert.AreEqual (typeof (InvalidOperationException), ex.GetType (), "#B2");
307                                 Assert.IsNull (ex.InnerException, "#B3");
308                                 Assert.IsNotNull (ex.Message, "#B4");
309                         }
310                 }
311
312                 [Test] // Start (ProcessStartInfo)
313                 public void Start2_FileName_NotFound ()
314                 {
315                         ProcessStartInfo startInfo = new ProcessStartInfo ();
316                         string exe = RunningOnUnix ? exe = "/usr/bin/shouldnoteverexist"
317                                 : @"c:\shouldnoteverexist.exe";
318
319                         // absolute path, no shell
320                         startInfo.FileName = exe;
321                         startInfo.UseShellExecute = false;
322                         try {
323                                 Process.Start (startInfo);
324                                 Assert.Fail ("#A1");
325                         } catch (Win32Exception ex) {
326                                 // The system cannot find the file specified
327                                 Assert.AreEqual (typeof (Win32Exception), ex.GetType (), "#A2");
328                                 Assert.AreEqual (-2147467259, ex.ErrorCode, "#A3");
329                                 Assert.IsNull (ex.InnerException, "#A4");
330                                 Assert.IsNotNull (ex.Message, "#A5");
331                                 Assert.AreEqual (2, ex.NativeErrorCode, "#A6");
332                         }
333
334                         // relative path, no shell
335                         startInfo.FileName = "shouldnoteverexist.exe";
336                         startInfo.UseShellExecute = false;
337                         try {
338                                 Process.Start (startInfo);
339                                 Assert.Fail ("#B1");
340                         } catch (Win32Exception ex) {
341                                 // The system cannot find the file specified
342                                 Assert.AreEqual (typeof (Win32Exception), ex.GetType (), "#B2");
343                                 Assert.AreEqual (-2147467259, ex.ErrorCode, "#B3");
344                                 Assert.IsNull (ex.InnerException, "#B4");
345                                 Assert.IsNotNull (ex.Message, "#B5");
346                                 Assert.AreEqual (2, ex.NativeErrorCode, "#B6");
347                         }
348
349                         if (RunningOnUnix)
350                                 Assert.Ignore ("On Unix and Mac OS X, we try " +
351                                         "to open any file (using xdg-open, ...)" +
352                                         " and we do not report an exception " +
353                                         "if this fails.");
354
355                         // absolute path, shell
356                         startInfo.FileName = exe;
357                         startInfo.UseShellExecute = true;
358                         try {
359                                 Process.Start (startInfo);
360                                 Assert.Fail ("#C1");
361                         } catch (Win32Exception ex) {
362                                 // The system cannot find the file specified
363                                 Assert.AreEqual (typeof (Win32Exception), ex.GetType (), "#C2");
364                                 Assert.AreEqual (-2147467259, ex.ErrorCode, "#C3");
365                                 Assert.IsNull (ex.InnerException, "#C4");
366                                 Assert.IsNotNull (ex.Message, "#C5");
367                                 Assert.AreEqual (2, ex.NativeErrorCode, "#C6");
368                         }
369
370                         // relative path, shell
371                         startInfo.FileName = "shouldnoteverexist.exe";
372                         startInfo.UseShellExecute = true;
373                         try {
374                                 Process.Start (startInfo);
375                                 Assert.Fail ("#D1");
376                         } catch (Win32Exception ex) {
377                                 // The system cannot find the file specified
378                                 Assert.AreEqual (typeof (Win32Exception), ex.GetType (), "#D2");
379                                 Assert.AreEqual (-2147467259, ex.ErrorCode, "#D3");
380                                 Assert.IsNull (ex.InnerException, "#D4");
381                                 Assert.IsNotNull (ex.Message, "#D5");
382                                 Assert.AreEqual (2, ex.NativeErrorCode, "#D6");
383                         }
384                 }
385
386                 [Test] // Start (ProcessStartInfo)
387                 public void Start2_FileName_Null ()
388                 {
389                         ProcessStartInfo startInfo = new ProcessStartInfo ((string) null);
390
391                         // no shell
392                         startInfo.UseShellExecute = false;
393                         try {
394                                 Process.Start (startInfo);
395                                 Assert.Fail ("#A1");
396                         } catch (InvalidOperationException ex) {
397                                 // Cannot start process because a file name has
398                                 // not been provided
399                                 Assert.AreEqual (typeof (InvalidOperationException), ex.GetType (), "#A2");
400                                 Assert.IsNull (ex.InnerException, "#A3");
401                                 Assert.IsNotNull (ex.Message, "#A4");
402                         }
403
404                         // shell
405                         startInfo.UseShellExecute = true;
406                         try {
407                                 Process.Start (startInfo);
408                                 Assert.Fail ("#B1");
409                         } catch (InvalidOperationException ex) {
410                                 // Cannot start process because a file name has
411                                 // not been provided
412                                 Assert.AreEqual (typeof (InvalidOperationException), ex.GetType (), "#B2");
413                                 Assert.IsNull (ex.InnerException, "#B3");
414                                 Assert.IsNotNull (ex.Message, "#B4");
415                         }
416                 }
417
418                 [Test] // Start (ProcessStartInfo)
419                 public void Start2_FileName_Whitespace ()
420                 {
421                         ProcessStartInfo startInfo = new ProcessStartInfo (" ");
422                         startInfo.UseShellExecute = false;
423                         try {
424                                 Process.Start (startInfo);
425                                 Assert.Fail ("#1");
426                         } catch (Win32Exception ex) {
427                                 // The system cannot find the file specified
428                                 Assert.AreEqual (typeof (Win32Exception), ex.GetType (), "#2");
429                                 Assert.AreEqual (-2147467259, ex.ErrorCode, "#3");
430                                 Assert.IsNull (ex.InnerException, "#4");
431                                 Assert.IsNotNull (ex.Message, "#5");
432                                 Assert.AreEqual (2, ex.NativeErrorCode, "#6");
433                         }
434                 }
435
436                 [Test] // Start (ProcessStartInfo)
437                 public void Start2_StartInfo_Null ()
438                 {
439                         try {
440                                 Process.Start ((ProcessStartInfo) null);
441                                 Assert.Fail ("#1");
442                         } catch (ArgumentNullException ex) {
443                                 Assert.AreEqual (typeof (ArgumentNullException), ex.GetType (), "#2");
444                                 Assert.IsNull (ex.InnerException, "#3");
445                                 Assert.IsNotNull (ex.Message, "#4");
446                                 Assert.IsNotNull (ex.ParamName, "#5");
447                                 Assert.AreEqual ("startInfo", ex.ParamName, "#6");
448                         }
449                 }
450
451                 [Test] // Start (string)
452                 public void Start3_FileName_Empty ()
453                 {
454                         try {
455                                 Process.Start (string.Empty);
456                                 Assert.Fail ("#1");
457                         } catch (InvalidOperationException ex) {
458                                 // Cannot start process because a file name has
459                                 // not been provided
460                                 Assert.AreEqual (typeof (InvalidOperationException), ex.GetType (), "#2");
461                                 Assert.IsNull (ex.InnerException, "#3");
462                                 Assert.IsNotNull (ex.Message, "#4");
463                         }
464                 }
465
466                 [Test] // Start (string)
467                 public void Start3_FileName_NotFound ()
468                 {
469                         if (RunningOnUnix)
470                                 Assert.Ignore ("On Unix and Mac OS X, we try " +
471                                         "to open any file (using xdg-open, ...)" +
472                                         " and we do not report an exception " +
473                                         "if this fails.");
474
475                         string exe = @"c:\shouldnoteverexist.exe";
476
477                         // absolute path, no shell
478                         try {
479                                 Process.Start (exe);
480                                 Assert.Fail ("#A1");
481                         } catch (Win32Exception ex) {
482                                 // The system cannot find the file specified
483                                 Assert.AreEqual (typeof (Win32Exception), ex.GetType (), "#A2");
484                                 Assert.AreEqual (-2147467259, ex.ErrorCode, "#A3");
485                                 Assert.IsNull (ex.InnerException, "#A4");
486                                 Assert.IsNotNull (ex.Message, "#A5");
487                                 Assert.AreEqual (2, ex.NativeErrorCode, "#A6");
488                         }
489
490                         // relative path, no shell
491                         try {
492                                 Process.Start ("shouldnoteverexist.exe");
493                                 Assert.Fail ("#B1");
494                         } catch (Win32Exception ex) {
495                                 // The system cannot find the file specified
496                                 Assert.AreEqual (typeof (Win32Exception), ex.GetType (), "#B2");
497                                 Assert.AreEqual (-2147467259, ex.ErrorCode, "#B3");
498                                 Assert.IsNull (ex.InnerException, "#B4");
499                                 Assert.IsNotNull (ex.Message, "#B5");
500                                 Assert.AreEqual (2, ex.NativeErrorCode, "#B6");
501                         }
502                 }
503
504                 [Test] // Start (string)
505                 public void Start3_FileName_Null ()
506                 {
507                         try {
508                                 Process.Start ((string) null);
509                                 Assert.Fail ("#1");
510                         } catch (InvalidOperationException ex) {
511                                 // Cannot start process because a file name has
512                                 // not been provided
513                                 Assert.AreEqual (typeof (InvalidOperationException), ex.GetType (), "#2");
514                                 Assert.IsNull (ex.InnerException, "#3");
515                                 Assert.IsNotNull (ex.Message, "#4");
516                         }
517                 }
518
519                 [Test] // Start (string, string)
520                 public void Start4_Arguments_Null ()
521                 {
522                         if (RunningOnUnix)
523                                 Assert.Ignore ("On Unix and Mac OS X, we try " +
524                                         "to open any file (using xdg-open, ...)" +
525                                         " and we do not report an exception " +
526                                         "if this fails.");
527
528                         string exe = @"c:\shouldnoteverexist.exe";
529
530                         try {
531                                 Process.Start ("whatever.exe", (string) null);
532                                 Assert.Fail ("#1");
533                         } catch (Win32Exception ex) {
534                                 // The system cannot find the file specified
535                                 Assert.AreEqual (typeof (Win32Exception), ex.GetType (), "#B2");
536                                 Assert.AreEqual (-2147467259, ex.ErrorCode, "#B3");
537                                 Assert.IsNull (ex.InnerException, "#B4");
538                                 Assert.IsNotNull (ex.Message, "#B5");
539                                 Assert.AreEqual (2, ex.NativeErrorCode, "#B6");
540                         }
541                 }
542
543                 [Test] // Start (string, string)
544                 public void Start4_FileName_Empty ()
545                 {
546                         try {
547                                 Process.Start (string.Empty, string.Empty);
548                                 Assert.Fail ("#1");
549                         } catch (InvalidOperationException ex) {
550                                 // Cannot start process because a file name has
551                                 // not been provided
552                                 Assert.AreEqual (typeof (InvalidOperationException), ex.GetType (), "#2");
553                                 Assert.IsNull (ex.InnerException, "#3");
554                                 Assert.IsNotNull (ex.Message, "#4");
555                         }
556                 }
557
558                 [Test] // Start (string, string)
559                 public void Start4_FileName_NotFound ()
560                 {
561                         if (RunningOnUnix)
562                                 Assert.Ignore ("On Unix and Mac OS X, we try " +
563                                         "to open any file (using xdg-open, ...)" +
564                                         " and we do not report an exception " +
565                                         "if this fails.");
566
567                         string exe = @"c:\shouldnoteverexist.exe";
568
569                         // absolute path, no shell
570                         try {
571                                 Process.Start (exe, string.Empty);
572                                 Assert.Fail ("#A1");
573                         } catch (Win32Exception ex) {
574                                 // The system cannot find the file specified
575                                 Assert.AreEqual (typeof (Win32Exception), ex.GetType (), "#A2");
576                                 Assert.AreEqual (-2147467259, ex.ErrorCode, "#A3");
577                                 Assert.IsNull (ex.InnerException, "#A4");
578                                 Assert.IsNotNull (ex.Message, "#A5");
579                                 Assert.AreEqual (2, ex.NativeErrorCode, "#A6");
580                         }
581
582                         // relative path, no shell
583                         try {
584                                 Process.Start ("shouldnoteverexist.exe", string.Empty);
585                                 Assert.Fail ("#B1");
586                         } catch (Win32Exception ex) {
587                                 // The system cannot find the file specified
588                                 Assert.AreEqual (typeof (Win32Exception), ex.GetType (), "#B2");
589                                 Assert.AreEqual (-2147467259, ex.ErrorCode, "#B3");
590                                 Assert.IsNull (ex.InnerException, "#B4");
591                                 Assert.IsNotNull (ex.Message, "#B5");
592                                 Assert.AreEqual (2, ex.NativeErrorCode, "#B6");
593                         }
594                 }
595
596                 [Test]
597                 public void Start_UseShellExecuteWithEmptyUserName ()
598                 {
599                         if (RunningOnUnix)
600                                 Assert.Ignore ("On Unix and Mac OS X, we try " +
601                                         "to open any file (using xdg-open, ...)" +
602                                         " and we do not report an exception " +
603                                         "if this fails.");
604
605                         string exe = @"c:\shouldnoteverexist.exe";
606
607                         try {
608                                 Process p = new Process ();
609                                 p.StartInfo.FileName = exe;
610                                 p.StartInfo.UseShellExecute = true;
611                                 p.StartInfo.UserName = "";
612                                 p.Start ();
613                                 Assert.Fail ("#1");
614                         } catch (InvalidOperationException) {
615                                 Assert.Fail ("#2");
616                         } catch (Win32Exception) {
617                         }
618
619                         try {
620                                 Process p = new Process ();
621                                 p.StartInfo.FileName = exe;
622                                 p.StartInfo.UseShellExecute = true;
623                                 p.StartInfo.UserName = null;
624                                 p.Start ();
625                                 Assert.Fail ("#3");                             
626                         } catch (InvalidOperationException) {
627                                 Assert.Fail ("#4");
628                         } catch (Win32Exception) {
629                         }
630                 }
631                 
632                 [Test] // Start (string, string)
633                 public void Start4_FileName_Null ()
634                 {
635                         try {
636                                 Process.Start ((string) null, string.Empty);
637                                 Assert.Fail ("#1");
638                         } catch (InvalidOperationException ex) {
639                                 // Cannot start process because a file name has
640                                 // not been provided
641                                 Assert.AreEqual (typeof (InvalidOperationException), ex.GetType (), "#2");
642                                 Assert.IsNull (ex.InnerException, "#3");
643                                 Assert.IsNotNull (ex.Message, "#4");
644                         }
645                 }
646
647                 [Test]
648                 public void StartInfo ()
649                 {
650                         ProcessStartInfo startInfo = new ProcessStartInfo ();
651
652                         Process p = new Process ();
653                         Assert.IsNotNull (p.StartInfo, "#A1");
654                         p.StartInfo = startInfo;
655                         Assert.AreSame (startInfo, p.StartInfo, "#A2");
656                 }
657
658                 [Test]
659                 public void StartInfo_Null ()
660                 {
661                         Process p = new Process ();
662                         try {
663                                 p.StartInfo = null;
664                                 Assert.Fail ("#1");
665                         } catch (ArgumentNullException ex) {
666                                 Assert.AreEqual (typeof (ArgumentNullException), ex.GetType (), "#2");
667                                 Assert.IsNull (ex.InnerException, "#3");
668                                 Assert.IsNotNull (ex.Message, "#4");
669                                 Assert.IsNotNull (ex.ParamName, "#5");
670                                 Assert.AreEqual ("value", ex.ParamName, "#6");
671                         }
672                 }
673
674                 [Test]
675                 [NUnit.Framework.Category ("NotDotNet")]
676                 [NUnit.Framework.Category ("MobileNotWorking")]
677                 public void TestRedirectedOutputIsAsync ()
678                 {
679                         // Test requires cygwin, so we just bail out for now.
680                         if (Path.DirectorySeparatorChar == '\\')
681                                 Assert.Ignore ("Test requires cygwin.");
682                         
683                         Process p = new Process ();
684                         p.StartInfo = new ProcessStartInfo ("/bin/sh", "-c \"sleep 2; echo hello\"");
685                         p.StartInfo.RedirectStandardOutput = true;
686                         p.StartInfo.UseShellExecute = false;
687                         p.Start ();
688
689                         Stream stdout = p.StandardOutput.BaseStream;
690
691                         byte [] buffer = new byte [200];
692
693                         // start async Read operation
694                         DateTime start = DateTime.Now;
695                         IAsyncResult ar = stdout.BeginRead (buffer, 0, buffer.Length,
696                                                             new AsyncCallback (Read), stdout);
697
698                         Assert.IsTrue ((DateTime.Now - start).TotalMilliseconds < 1000, "#01 BeginRead was not async");
699                         p.WaitForExit ();
700                         Assert.AreEqual (0, p.ExitCode, "#02 script failure");
701
702                         /*
703                         ar.AsyncWaitHandle.WaitOne (2000, false);
704                         if (bytesRead < "hello".Length)
705                                 Assert.Fail ("#03 got {0} bytes", bytesRead);
706                         Assert.AreEqual ("hello", Encoding.Default.GetString (buffer, 0, 5), "#04");
707                         */
708                 }
709                 
710                 void Read (IAsyncResult ar)
711                 {
712                         Stream stm = (Stream) ar.AsyncState;
713                         bytesRead = stm.EndRead (ar);
714                 }
715
716                 static bool RunningOnUnix {
717                         get {
718                                 int p = (int)Environment.OSVersion.Platform;
719                                 return ((p == 128) || (p == 4) || (p == 6));
720                         }
721                 }
722
723                 public int bytesRead = -1;
724
725 // Not technically a 2.0 only test, but I use lambdas, so I need gmcs
726
727                 [Test]
728                 [NUnit.Framework.Category ("MobileNotWorking")]
729                 // This was for bug #459450
730                 public void TestEventRaising ()
731                 {
732                         EventWaitHandle errorClosed = new ManualResetEvent(false);
733                         EventWaitHandle outClosed = new ManualResetEvent(false);
734                         EventWaitHandle exited = new ManualResetEvent(false);
735
736                         Process p = new Process();
737                         
738                         p.StartInfo = GetCrossPlatformStartInfo ();
739                         p.StartInfo.UseShellExecute = false;
740                         p.StartInfo.RedirectStandardOutput = true;
741                         p.StartInfo.RedirectStandardError = true;
742                         p.StartInfo.RedirectStandardInput = false;
743                         p.OutputDataReceived += (object sender, DataReceivedEventArgs e) => {
744                                 if (e.Data == null) {
745                                         outClosed.Set();
746                                 }
747                         };
748                         
749                         p.ErrorDataReceived += (object sender, DataReceivedEventArgs e) => {
750                                 if (e.Data == null) {
751                                         errorClosed.Set();
752                                 }
753                         };
754                         
755                         p.Exited += (object sender, EventArgs e) => {
756                                 exited.Set ();
757                         };
758                         
759                         p.EnableRaisingEvents = true;
760
761                         p.Start();
762
763                         p.BeginErrorReadLine();
764                         p.BeginOutputReadLine();
765
766                         Console.WriteLine("started, waiting for handles");
767                         bool r = WaitHandle.WaitAll(new WaitHandle[] { errorClosed, outClosed, exited }, 10000, false);
768
769                         Assert.AreEqual (true, r, "Null Argument Events Raised");
770                 }
771
772                 [Test]
773                 [NUnit.Framework.Category ("MobileNotWorking")]
774                 public void TestEnableEventsAfterExitedEvent ()
775                 {
776                         Process p = new Process ();
777                         
778                         p.StartInfo = GetCrossPlatformStartInfo ();
779                         p.StartInfo.UseShellExecute = false;
780                         p.StartInfo.RedirectStandardOutput = true;
781                         p.StartInfo.RedirectStandardError = true;
782
783                         var exitedCalledCounter = 0;
784                         p.Exited += (object sender, EventArgs e) => {
785                                 exitedCalledCounter++;
786                                 Assert.IsTrue (p.HasExited);
787                         };
788
789                         p.EnableRaisingEvents = true;
790
791                         p.Start ();
792                         p.BeginErrorReadLine ();
793                         p.BeginOutputReadLine ();
794                         p.WaitForExit ();
795
796                         Assert.AreEqual (1, exitedCalledCounter);
797                         Thread.Sleep (50);
798                         Assert.AreEqual (1, exitedCalledCounter);
799                 }
800
801                 [Test]
802                 [NUnit.Framework.Category ("MobileNotWorking")]
803                 public void TestEnableEventsBeforeExitedEvent ()
804                 {
805                         Process p = new Process ();
806                         
807                         p.StartInfo = GetCrossPlatformStartInfo ();
808                         p.StartInfo.UseShellExecute = false;
809                         p.StartInfo.RedirectStandardOutput = true;
810                         p.StartInfo.RedirectStandardError = true;
811
812                         p.EnableRaisingEvents = true;
813
814                         var exitedCalledCounter = 0;
815                         p.Exited += (object sender, EventArgs e) => {
816                                 exitedCalledCounter++;
817                                 Assert.IsTrue (p.HasExited);
818                         };
819
820                         p.Start ();
821                         p.BeginErrorReadLine ();
822                         p.BeginOutputReadLine ();
823                         p.WaitForExit ();
824
825                         Assert.AreEqual (1, exitedCalledCounter);
826                         Thread.Sleep (50);
827                         Assert.AreEqual (1, exitedCalledCounter);
828                 }
829
830                 
831                 private ProcessStartInfo GetCrossPlatformStartInfo ()
832                 {
833                         return RunningOnUnix ? new ProcessStartInfo ("/bin/ls", "/") : new ProcessStartInfo ("help", "");
834                 }
835
836                 [Test] // Covers #26362
837                 public void TestExitedEvent ()
838                 {
839                         var falseExitedEvents = 0;
840                         var cp = Process.GetCurrentProcess ();
841                         foreach (var p in Process.GetProcesses ()) {
842                                 if (p.Id != cp.Id && !p.HasExited) {
843                                         p.EnableRaisingEvents = true;
844                                         p.Exited += (s, e) => {
845                                                 if (!p.HasExited)
846                                                         falseExitedEvents++;
847                                         };
848                                 }
849                         }
850                         Assert.AreEqual (0, falseExitedEvents);
851                 }
852                 
853                 [Test]
854                 public void ProcessName_NotStarted ()
855                 {
856                         Process p = new Process ();
857                         Exception e = null;
858                         try {
859                                 String.IsNullOrEmpty (p.ProcessName);
860                         } catch (Exception ex) {
861                                 e = ex;
862                         }
863                         
864                         Assert.IsNotNull (e, "ProcessName should raise if process was not started");
865                         
866                         //msg should be "No process is associated with this object"
867                         Assert.AreEqual (e.GetType (), typeof (InvalidOperationException),
868                                          "exception should be IOE, I got: " + e.GetType ().Name);
869                         
870                         Assert.IsNull (e.InnerException, "IOE inner exception should be null");
871                 }
872                 
873                 [Test]
874                 [NUnit.Framework.Category ("MobileNotWorking")]
875                 public void ProcessName_AfterExit ()
876                 {
877                         Process p = new Process ();
878                         p.StartInfo = GetCrossPlatformStartInfo ();
879                         p.StartInfo.UseShellExecute = false;
880                         p.StartInfo.RedirectStandardOutput = true;
881                         p.StartInfo.RedirectStandardError = true;
882                         p.Start ();
883                         p.BeginErrorReadLine();
884                         p.BeginOutputReadLine();
885                         p.WaitForExit ();
886                         String.IsNullOrEmpty (p.ExitCode + "");
887                         
888                         Exception e = null;
889                         try {
890                                 String.IsNullOrEmpty (p.ProcessName);
891                         } catch (Exception ex) {
892                                 e = ex;
893                         }
894                         
895                         Assert.IsNotNull (e, "ProcessName should raise if process was finished");
896                         
897                         //msg should be "Process has exited, so the requested information is not available"
898                         Assert.AreEqual (e.GetType (), typeof (InvalidOperationException),
899                                          "exception should be IOE, I got: " + e.GetType ().Name);
900                         
901                         Assert.IsNull (e.InnerException, "IOE inner exception should be null");
902                 }
903
904                 [Test]
905                 public void Handle_ThrowsOnNotStarted ()
906                 {
907                         Process p = new Process ();
908                         try {
909                                 var x = p.Handle;
910                                 Assert.Fail ("Handle should throw for unstated procs, but returned " + x);
911                         } catch (InvalidOperationException) {
912                         }
913                 }
914
915                 [Test]
916                 public void HasExitedCurrent () {
917                         Assert.IsFalse (Process.GetCurrentProcess ().HasExited);
918                 }
919         }
920 }