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