Merge pull request #2584 from lewurm/fix-mobile-compilation
[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                 [NUnit.Framework.Category ("MobileNotWorking")]
57                 public void GetProcesses_StartTime ()
58                 {
59                         foreach (var p in Process.GetProcesses ()) {
60                                 if (!p.HasExited && p.StartTime.Year < 1800)
61                                         Assert.Fail ("Process should not be started since the 18th century.");
62                         }
63                 }
64
65                 [Test]
66                 public void PriorityClass_NotStarted ()
67                 {
68                         Process process = new Process ();
69                         try {
70                                 process.PriorityClass = ProcessPriorityClass.Normal;
71                                 Assert.Fail ("#A1");
72                         } catch (InvalidOperationException ex) {
73                                 // No process is associated with this object
74                                 Assert.AreEqual (typeof (InvalidOperationException), ex.GetType (), "#A2");
75                                 Assert.IsNull (ex.InnerException, "#A3");
76                                 Assert.IsNotNull (ex.Message, "#A4");
77                         }
78
79                         try {
80                                 Assert.Fail ("#B1:" + process.PriorityClass);
81                         } catch (InvalidOperationException ex) {
82                                 // No process is associated with this object
83                                 Assert.AreEqual (typeof (InvalidOperationException), ex.GetType (), "#B2");
84                                 Assert.IsNull (ex.InnerException, "#B3");
85                                 Assert.IsNotNull (ex.Message, "#B4");
86                         }
87                 }
88
89                 [Test]
90                 public void PriorityClass_Invalid ()
91                 {
92                         Process process = new Process ();
93                         try {
94                                 process.PriorityClass = (ProcessPriorityClass) 666;
95                                 Assert.Fail ("#1");
96                         } catch (InvalidEnumArgumentException ex) {
97                                 Assert.AreEqual (typeof (InvalidEnumArgumentException), ex.GetType (), "#2");
98                                 Assert.IsNull (ex.InnerException, "#3");
99                                 Assert.IsNotNull (ex.Message, "#4");
100                                 Assert.IsTrue (ex.Message.IndexOf ("666") != -1, "#5");
101                                 Assert.IsTrue (ex.Message.IndexOf (typeof (ProcessPriorityClass).Name) != -1, "#6");
102                                 Assert.IsNotNull (ex.ParamName, "#7");
103                                 Assert.AreEqual ("value", ex.ParamName, "#8");
104                         }
105                 }
106
107 #if MONO_FEATURE_PROCESS_START
108                 [Test] // Start ()
109                 public void Start1_FileName_Empty ()
110                 {
111                         Process process = new Process ();
112                         process.StartInfo = new ProcessStartInfo (string.Empty);
113
114                         // no shell
115                         process.StartInfo.UseShellExecute = false;
116                         try {
117                                 process.Start ();
118                                 Assert.Fail ("#A1");
119                         } catch (InvalidOperationException ex) {
120                                 // Cannot start process because a file name has
121                                 // not been provided
122                                 Assert.AreEqual (typeof (InvalidOperationException), ex.GetType (), "#A2");
123                                 Assert.IsNull (ex.InnerException, "#A3");
124                                 Assert.IsNotNull (ex.Message, "#A4");
125                         }
126
127                         // shell
128                         process.StartInfo.UseShellExecute = true;
129                         try {
130                                 process.Start ();
131                                 Assert.Fail ("#B1");
132                         } catch (InvalidOperationException ex) {
133                                 // Cannot start process because a file name has
134                                 // not been provided
135                                 Assert.AreEqual (typeof (InvalidOperationException), ex.GetType (), "#B2");
136                                 Assert.IsNull (ex.InnerException, "#B3");
137                                 Assert.IsNotNull (ex.Message, "#B4");
138                         }
139                 }
140
141                 [Test] // Start ()
142                 public void Start1_FileName_InvalidPathCharacters ()
143                 {
144                         if (RunningOnUnix)
145                                 // on unix, all characters are allowed
146                                 Assert.Ignore ("Running on Unix.");
147
148                         string systemDir = Environment.GetFolderPath (Environment.SpecialFolder.System);
149                         string exe = "\"" + Path.Combine (systemDir, "calc.exe") + "\"";
150
151                         Process process = new Process ();
152                         process.StartInfo = new ProcessStartInfo (exe);
153
154                         // no shell
155                         process.StartInfo.UseShellExecute = false;
156                         Assert.IsTrue (process.Start ());
157                         process.Kill ();
158
159                         // shell
160                         process.StartInfo.UseShellExecute = true;
161                         Assert.IsTrue (process.Start ());
162                         process.Kill ();
163                 }
164
165                 [Test] // Start ()
166                 public void Start1_FileName_NotFound ()
167                 {
168                         Process process = new Process ();
169                         string exe = RunningOnUnix ? exe = "/usr/bin/shouldnoteverexist"
170                                 : @"c:\shouldnoteverexist.exe";
171
172                         // absolute path, no shell
173                         process.StartInfo = new ProcessStartInfo (exe);
174                         process.StartInfo.UseShellExecute = false;
175                         try {
176                                 process.Start ();
177                                 Assert.Fail ("#A1");
178                         } catch (Win32Exception ex) {
179                                 // The system cannot find the file specified
180                                 Assert.AreEqual (typeof (Win32Exception), ex.GetType (), "#A2");
181                                 Assert.AreEqual (-2147467259, ex.ErrorCode, "#A3");
182                                 Assert.IsNull (ex.InnerException, "#A4");
183                                 Assert.IsNotNull (ex.Message, "#A5");
184                                 Assert.AreEqual (2, ex.NativeErrorCode, "#A6");
185                         }
186
187                         // relative path, no shell
188                         process.StartInfo.FileName = "shouldnoteverexist.exe";
189                         process.StartInfo.UseShellExecute = false;
190                         try {
191                                 process.Start ();
192                                 Assert.Fail ("#B1");
193                         } catch (Win32Exception ex) {
194                                 // The system cannot find the file specified
195                                 Assert.AreEqual (typeof (Win32Exception), ex.GetType (), "#B2");
196                                 Assert.AreEqual (-2147467259, ex.ErrorCode, "#B3");
197                                 Assert.IsNull (ex.InnerException, "#B4");
198                                 Assert.IsNotNull (ex.Message, "#B5");
199                                 Assert.AreEqual (2, ex.NativeErrorCode, "#B6");
200                         }
201
202                         if (RunningOnUnix)
203                                 Assert.Ignore ("On Unix and Mac OS X, we try " +
204                                         "to open any file (using xdg-open, ...)" +
205                                         " and we do not report an exception " +
206                                         "if this fails.");
207
208                         // absolute path, shell
209                         process.StartInfo.FileName = exe;
210                         process.StartInfo.UseShellExecute = true;
211                         try {
212                                 process.Start ();
213                                 Assert.Fail ("#C1");
214                         } catch (Win32Exception ex) {
215                                 // The system cannot find the file specified
216                                 Assert.AreEqual (typeof (Win32Exception), ex.GetType (), "#C2");
217                                 Assert.AreEqual (-2147467259, ex.ErrorCode, "#C3");
218                                 Assert.IsNull (ex.InnerException, "#C4");
219                                 Assert.IsNotNull (ex.Message, "#C5");
220                                 Assert.AreEqual (2, ex.NativeErrorCode, "#C6");
221                         }
222
223                         // relative path, shell
224                         process.StartInfo.FileName = "shouldnoteverexist.exe";
225                         process.StartInfo.UseShellExecute = true;
226                         try {
227                                 process.Start ();
228                                 Assert.Fail ("#D1");
229                         } catch (Win32Exception ex) {
230                                 // The system cannot find the file specified
231                                 Assert.AreEqual (typeof (Win32Exception), ex.GetType (), "#D2");
232                                 Assert.AreEqual (-2147467259, ex.ErrorCode, "#D3");
233                                 Assert.IsNull (ex.InnerException, "#D4");
234                                 Assert.IsNotNull (ex.Message, "#D5");
235                                 Assert.AreEqual (2, ex.NativeErrorCode, "#D6");
236                         }
237                 }
238
239                 [Test] // Start ()
240                 public void Start1_FileName_Null ()
241                 {
242                         Process process = new Process ();
243                         process.StartInfo = new ProcessStartInfo ((string) null);
244
245                         // no shell
246                         process.StartInfo.UseShellExecute = false;
247                         try {
248                                 process.Start ();
249                                 Assert.Fail ("#A1");
250                         } catch (InvalidOperationException ex) {
251                                 // Cannot start process because a file name has
252                                 // not been provided
253                                 Assert.AreEqual (typeof (InvalidOperationException), ex.GetType (), "#A2");
254                                 Assert.IsNull (ex.InnerException, "#A3");
255                                 Assert.IsNotNull (ex.Message, "#A4");
256                         }
257
258                         // shell
259                         process.StartInfo.UseShellExecute = true;
260                         try {
261                                 process.Start ();
262                                 Assert.Fail ("#B1");
263                         } catch (InvalidOperationException ex) {
264                                 // Cannot start process because a file name has
265                                 // not been provided
266                                 Assert.AreEqual (typeof (InvalidOperationException), ex.GetType (), "#B2");
267                                 Assert.IsNull (ex.InnerException, "#B3");
268                                 Assert.IsNotNull (ex.Message, "#B4");
269                         }
270                 }
271
272                 [Test] // Start ()
273                 public void Start1_FileName_Whitespace ()
274                 {
275                         Process process = new Process ();
276                         process.StartInfo = new ProcessStartInfo (" ");
277                         process.StartInfo.UseShellExecute = false;
278                         try {
279                                 process.Start ();
280                                 Assert.Fail ("#1");
281                         } catch (Win32Exception ex) {
282                                 // The system cannot find the file specified
283                                 Assert.AreEqual (typeof (Win32Exception), ex.GetType (), "#2");
284                                 Assert.AreEqual (-2147467259, ex.ErrorCode, "#3");
285                                 Assert.IsNull (ex.InnerException, "#4");
286                                 Assert.IsNotNull (ex.Message, "#5");
287                                 Assert.AreEqual (2, ex.NativeErrorCode, "#6");
288                         }
289                 }
290
291                 [Test] // Start (ProcessStartInfo)
292                 public void Start2_FileName_Empty ()
293                 {
294                         ProcessStartInfo startInfo = new ProcessStartInfo (string.Empty);
295
296                         // no shell
297                         startInfo.UseShellExecute = false;
298                         try {
299                                 Process.Start (startInfo);
300                                 Assert.Fail ("#A1");
301                         } catch (InvalidOperationException ex) {
302                                 // Cannot start process because a file name has
303                                 // not been provided
304                                 Assert.AreEqual (typeof (InvalidOperationException), ex.GetType (), "#A2");
305                                 Assert.IsNull (ex.InnerException, "#A3");
306                                 Assert.IsNotNull (ex.Message, "#A4");
307                         }
308
309                         // shell
310                         startInfo.UseShellExecute = true;
311                         try {
312                                 Process.Start (startInfo);
313                                 Assert.Fail ("#B1");
314                         } catch (InvalidOperationException ex) {
315                                 // Cannot start process because a file name has
316                                 // not been provided
317                                 Assert.AreEqual (typeof (InvalidOperationException), ex.GetType (), "#B2");
318                                 Assert.IsNull (ex.InnerException, "#B3");
319                                 Assert.IsNotNull (ex.Message, "#B4");
320                         }
321                 }
322
323                 [Test] // Start (ProcessStartInfo)
324                 public void Start2_FileName_NotFound ()
325                 {
326                         ProcessStartInfo startInfo = new ProcessStartInfo ();
327                         string exe = RunningOnUnix ? exe = "/usr/bin/shouldnoteverexist"
328                                 : @"c:\shouldnoteverexist.exe";
329
330                         // absolute path, no shell
331                         startInfo.FileName = exe;
332                         startInfo.UseShellExecute = false;
333                         try {
334                                 Process.Start (startInfo);
335                                 Assert.Fail ("#A1");
336                         } catch (Win32Exception ex) {
337                                 // The system cannot find the file specified
338                                 Assert.AreEqual (typeof (Win32Exception), ex.GetType (), "#A2");
339                                 Assert.AreEqual (-2147467259, ex.ErrorCode, "#A3");
340                                 Assert.IsNull (ex.InnerException, "#A4");
341                                 Assert.IsNotNull (ex.Message, "#A5");
342                                 Assert.AreEqual (2, ex.NativeErrorCode, "#A6");
343                         }
344
345                         // relative path, no shell
346                         startInfo.FileName = "shouldnoteverexist.exe";
347                         startInfo.UseShellExecute = false;
348                         try {
349                                 Process.Start (startInfo);
350                                 Assert.Fail ("#B1");
351                         } catch (Win32Exception ex) {
352                                 // The system cannot find the file specified
353                                 Assert.AreEqual (typeof (Win32Exception), ex.GetType (), "#B2");
354                                 Assert.AreEqual (-2147467259, ex.ErrorCode, "#B3");
355                                 Assert.IsNull (ex.InnerException, "#B4");
356                                 Assert.IsNotNull (ex.Message, "#B5");
357                                 Assert.AreEqual (2, ex.NativeErrorCode, "#B6");
358                         }
359
360                         if (RunningOnUnix)
361                                 Assert.Ignore ("On Unix and Mac OS X, we try " +
362                                         "to open any file (using xdg-open, ...)" +
363                                         " and we do not report an exception " +
364                                         "if this fails.");
365
366                         // absolute path, shell
367                         startInfo.FileName = exe;
368                         startInfo.UseShellExecute = true;
369                         try {
370                                 Process.Start (startInfo);
371                                 Assert.Fail ("#C1");
372                         } catch (Win32Exception ex) {
373                                 // The system cannot find the file specified
374                                 Assert.AreEqual (typeof (Win32Exception), ex.GetType (), "#C2");
375                                 Assert.AreEqual (-2147467259, ex.ErrorCode, "#C3");
376                                 Assert.IsNull (ex.InnerException, "#C4");
377                                 Assert.IsNotNull (ex.Message, "#C5");
378                                 Assert.AreEqual (2, ex.NativeErrorCode, "#C6");
379                         }
380
381                         // relative path, shell
382                         startInfo.FileName = "shouldnoteverexist.exe";
383                         startInfo.UseShellExecute = true;
384                         try {
385                                 Process.Start (startInfo);
386                                 Assert.Fail ("#D1");
387                         } catch (Win32Exception ex) {
388                                 // The system cannot find the file specified
389                                 Assert.AreEqual (typeof (Win32Exception), ex.GetType (), "#D2");
390                                 Assert.AreEqual (-2147467259, ex.ErrorCode, "#D3");
391                                 Assert.IsNull (ex.InnerException, "#D4");
392                                 Assert.IsNotNull (ex.Message, "#D5");
393                                 Assert.AreEqual (2, ex.NativeErrorCode, "#D6");
394                         }
395                 }
396
397                 [Test] // Start (ProcessStartInfo)
398                 public void Start2_FileName_Null ()
399                 {
400                         ProcessStartInfo startInfo = new ProcessStartInfo ((string) null);
401
402                         // no shell
403                         startInfo.UseShellExecute = false;
404                         try {
405                                 Process.Start (startInfo);
406                                 Assert.Fail ("#A1");
407                         } catch (InvalidOperationException ex) {
408                                 // Cannot start process because a file name has
409                                 // not been provided
410                                 Assert.AreEqual (typeof (InvalidOperationException), ex.GetType (), "#A2");
411                                 Assert.IsNull (ex.InnerException, "#A3");
412                                 Assert.IsNotNull (ex.Message, "#A4");
413                         }
414
415                         // shell
416                         startInfo.UseShellExecute = true;
417                         try {
418                                 Process.Start (startInfo);
419                                 Assert.Fail ("#B1");
420                         } catch (InvalidOperationException ex) {
421                                 // Cannot start process because a file name has
422                                 // not been provided
423                                 Assert.AreEqual (typeof (InvalidOperationException), ex.GetType (), "#B2");
424                                 Assert.IsNull (ex.InnerException, "#B3");
425                                 Assert.IsNotNull (ex.Message, "#B4");
426                         }
427                 }
428
429                 [Test] // Start (ProcessStartInfo)
430                 public void Start2_FileName_Whitespace ()
431                 {
432                         ProcessStartInfo startInfo = new ProcessStartInfo (" ");
433                         startInfo.UseShellExecute = false;
434                         try {
435                                 Process.Start (startInfo);
436                                 Assert.Fail ("#1");
437                         } catch (Win32Exception ex) {
438                                 // The system cannot find the file specified
439                                 Assert.AreEqual (typeof (Win32Exception), ex.GetType (), "#2");
440                                 Assert.AreEqual (-2147467259, ex.ErrorCode, "#3");
441                                 Assert.IsNull (ex.InnerException, "#4");
442                                 Assert.IsNotNull (ex.Message, "#5");
443                                 Assert.AreEqual (2, ex.NativeErrorCode, "#6");
444                         }
445                 }
446
447                 [Test] // Start (ProcessStartInfo)
448                 public void Start2_StartInfo_Null ()
449                 {
450                         try {
451                                 Process.Start ((ProcessStartInfo) null);
452                                 Assert.Fail ("#1");
453                         } catch (ArgumentNullException ex) {
454                                 Assert.AreEqual (typeof (ArgumentNullException), ex.GetType (), "#2");
455                                 Assert.IsNull (ex.InnerException, "#3");
456                                 Assert.IsNotNull (ex.Message, "#4");
457                                 Assert.IsNotNull (ex.ParamName, "#5");
458                                 Assert.AreEqual ("startInfo", ex.ParamName, "#6");
459                         }
460                 }
461
462                 [Test] // Start (string)
463                 public void Start3_FileName_Empty ()
464                 {
465                         try {
466                                 Process.Start (string.Empty);
467                                 Assert.Fail ("#1");
468                         } catch (InvalidOperationException ex) {
469                                 // Cannot start process because a file name has
470                                 // not been provided
471                                 Assert.AreEqual (typeof (InvalidOperationException), ex.GetType (), "#2");
472                                 Assert.IsNull (ex.InnerException, "#3");
473                                 Assert.IsNotNull (ex.Message, "#4");
474                         }
475                 }
476
477                 [Test] // Start (string)
478                 public void Start3_FileName_NotFound ()
479                 {
480                         if (RunningOnUnix)
481                                 Assert.Ignore ("On Unix and Mac OS X, we try " +
482                                         "to open any file (using xdg-open, ...)" +
483                                         " and we do not report an exception " +
484                                         "if this fails.");
485
486                         string exe = @"c:\shouldnoteverexist.exe";
487
488                         // absolute path, no shell
489                         try {
490                                 Process.Start (exe);
491                                 Assert.Fail ("#A1");
492                         } catch (Win32Exception ex) {
493                                 // The system cannot find the file specified
494                                 Assert.AreEqual (typeof (Win32Exception), ex.GetType (), "#A2");
495                                 Assert.AreEqual (-2147467259, ex.ErrorCode, "#A3");
496                                 Assert.IsNull (ex.InnerException, "#A4");
497                                 Assert.IsNotNull (ex.Message, "#A5");
498                                 Assert.AreEqual (2, ex.NativeErrorCode, "#A6");
499                         }
500
501                         // relative path, no shell
502                         try {
503                                 Process.Start ("shouldnoteverexist.exe");
504                                 Assert.Fail ("#B1");
505                         } catch (Win32Exception ex) {
506                                 // The system cannot find the file specified
507                                 Assert.AreEqual (typeof (Win32Exception), ex.GetType (), "#B2");
508                                 Assert.AreEqual (-2147467259, ex.ErrorCode, "#B3");
509                                 Assert.IsNull (ex.InnerException, "#B4");
510                                 Assert.IsNotNull (ex.Message, "#B5");
511                                 Assert.AreEqual (2, ex.NativeErrorCode, "#B6");
512                         }
513                 }
514
515                 [Test] // Start (string)
516                 public void Start3_FileName_Null ()
517                 {
518                         try {
519                                 Process.Start ((string) null);
520                                 Assert.Fail ("#1");
521                         } catch (InvalidOperationException ex) {
522                                 // Cannot start process because a file name has
523                                 // not been provided
524                                 Assert.AreEqual (typeof (InvalidOperationException), ex.GetType (), "#2");
525                                 Assert.IsNull (ex.InnerException, "#3");
526                                 Assert.IsNotNull (ex.Message, "#4");
527                         }
528                 }
529
530                 [Test] // Start (string, string)
531                 public void Start4_Arguments_Null ()
532                 {
533                         if (RunningOnUnix)
534                                 Assert.Ignore ("On Unix and Mac OS X, we try " +
535                                         "to open any file (using xdg-open, ...)" +
536                                         " and we do not report an exception " +
537                                         "if this fails.");
538
539                         string exe = @"c:\shouldnoteverexist.exe";
540
541                         try {
542                                 Process.Start ("whatever.exe", (string) null);
543                                 Assert.Fail ("#1");
544                         } catch (Win32Exception ex) {
545                                 // The system cannot find the file specified
546                                 Assert.AreEqual (typeof (Win32Exception), ex.GetType (), "#B2");
547                                 Assert.AreEqual (-2147467259, ex.ErrorCode, "#B3");
548                                 Assert.IsNull (ex.InnerException, "#B4");
549                                 Assert.IsNotNull (ex.Message, "#B5");
550                                 Assert.AreEqual (2, ex.NativeErrorCode, "#B6");
551                         }
552                 }
553
554                 [Test] // Start (string, string)
555                 public void Start4_FileName_Empty ()
556                 {
557                         try {
558                                 Process.Start (string.Empty, string.Empty);
559                                 Assert.Fail ("#1");
560                         } catch (InvalidOperationException ex) {
561                                 // Cannot start process because a file name has
562                                 // not been provided
563                                 Assert.AreEqual (typeof (InvalidOperationException), ex.GetType (), "#2");
564                                 Assert.IsNull (ex.InnerException, "#3");
565                                 Assert.IsNotNull (ex.Message, "#4");
566                         }
567                 }
568
569                 [Test] // Start (string, string)
570                 public void Start4_FileName_NotFound ()
571                 {
572                         if (RunningOnUnix)
573                                 Assert.Ignore ("On Unix and Mac OS X, we try " +
574                                         "to open any file (using xdg-open, ...)" +
575                                         " and we do not report an exception " +
576                                         "if this fails.");
577
578                         string exe = @"c:\shouldnoteverexist.exe";
579
580                         // absolute path, no shell
581                         try {
582                                 Process.Start (exe, string.Empty);
583                                 Assert.Fail ("#A1");
584                         } catch (Win32Exception ex) {
585                                 // The system cannot find the file specified
586                                 Assert.AreEqual (typeof (Win32Exception), ex.GetType (), "#A2");
587                                 Assert.AreEqual (-2147467259, ex.ErrorCode, "#A3");
588                                 Assert.IsNull (ex.InnerException, "#A4");
589                                 Assert.IsNotNull (ex.Message, "#A5");
590                                 Assert.AreEqual (2, ex.NativeErrorCode, "#A6");
591                         }
592
593                         // relative path, no shell
594                         try {
595                                 Process.Start ("shouldnoteverexist.exe", string.Empty);
596                                 Assert.Fail ("#B1");
597                         } catch (Win32Exception ex) {
598                                 // The system cannot find the file specified
599                                 Assert.AreEqual (typeof (Win32Exception), ex.GetType (), "#B2");
600                                 Assert.AreEqual (-2147467259, ex.ErrorCode, "#B3");
601                                 Assert.IsNull (ex.InnerException, "#B4");
602                                 Assert.IsNotNull (ex.Message, "#B5");
603                                 Assert.AreEqual (2, ex.NativeErrorCode, "#B6");
604                         }
605                 }
606
607                 [Test]
608                 public void Start_UseShellExecuteWithEmptyUserName ()
609                 {
610                         if (RunningOnUnix)
611                                 Assert.Ignore ("On Unix and Mac OS X, we try " +
612                                         "to open any file (using xdg-open, ...)" +
613                                         " and we do not report an exception " +
614                                         "if this fails.");
615
616                         string exe = @"c:\shouldnoteverexist.exe";
617
618                         try {
619                                 Process p = new Process ();
620                                 p.StartInfo.FileName = exe;
621                                 p.StartInfo.UseShellExecute = true;
622                                 p.StartInfo.UserName = "";
623                                 p.Start ();
624                                 Assert.Fail ("#1");
625                         } catch (InvalidOperationException) {
626                                 Assert.Fail ("#2");
627                         } catch (Win32Exception) {
628                         }
629
630                         try {
631                                 Process p = new Process ();
632                                 p.StartInfo.FileName = exe;
633                                 p.StartInfo.UseShellExecute = true;
634                                 p.StartInfo.UserName = null;
635                                 p.Start ();
636                                 Assert.Fail ("#3");                             
637                         } catch (InvalidOperationException) {
638                                 Assert.Fail ("#4");
639                         } catch (Win32Exception) {
640                         }
641                 }
642                 
643                 [Test] // Start (string, string)
644                 public void Start4_FileName_Null ()
645                 {
646                         try {
647                                 Process.Start ((string) null, string.Empty);
648                                 Assert.Fail ("#1");
649                         } catch (InvalidOperationException ex) {
650                                 // Cannot start process because a file name has
651                                 // not been provided
652                                 Assert.AreEqual (typeof (InvalidOperationException), ex.GetType (), "#2");
653                                 Assert.IsNull (ex.InnerException, "#3");
654                                 Assert.IsNotNull (ex.Message, "#4");
655                         }
656                 }
657
658                 [Test]
659                 public void StartInfo ()
660                 {
661                         ProcessStartInfo startInfo = new ProcessStartInfo ();
662
663                         Process p = new Process ();
664                         Assert.IsNotNull (p.StartInfo, "#A1");
665                         p.StartInfo = startInfo;
666                         Assert.AreSame (startInfo, p.StartInfo, "#A2");
667                 }
668
669                 [Test]
670                 public void StartInfo_Null ()
671                 {
672                         Process p = new Process ();
673                         try {
674                                 p.StartInfo = null;
675                                 Assert.Fail ("#1");
676                         } catch (ArgumentNullException ex) {
677                                 Assert.AreEqual (typeof (ArgumentNullException), ex.GetType (), "#2");
678                                 Assert.IsNull (ex.InnerException, "#3");
679                                 Assert.IsNotNull (ex.Message, "#4");
680                                 Assert.IsNotNull (ex.ParamName, "#5");
681                                 Assert.AreEqual ("value", ex.ParamName, "#6");
682                         }
683                 }
684
685                 [Test]
686                 [NUnit.Framework.Category ("NotDotNet")]
687                 [NUnit.Framework.Category ("MobileNotWorking")]
688                 public void TestRedirectedOutputIsAsync ()
689                 {
690                         // Test requires cygwin, so we just bail out for now.
691                         if (Path.DirectorySeparatorChar == '\\')
692                                 Assert.Ignore ("Test requires cygwin.");
693                         
694                         Process p = new Process ();
695                         p.StartInfo = new ProcessStartInfo ("/bin/sh", "-c \"sleep 2; echo hello\"");
696                         p.StartInfo.RedirectStandardOutput = true;
697                         p.StartInfo.UseShellExecute = false;
698                         p.Start ();
699
700                         Stream stdout = p.StandardOutput.BaseStream;
701
702                         byte [] buffer = new byte [200];
703
704                         // start async Read operation
705                         DateTime start = DateTime.Now;
706                         IAsyncResult ar = stdout.BeginRead (buffer, 0, buffer.Length,
707                                                             new AsyncCallback (Read), stdout);
708
709                         Assert.IsTrue ((DateTime.Now - start).TotalMilliseconds < 1000, "#01 BeginRead was not async");
710                         p.WaitForExit ();
711                         Assert.AreEqual (0, p.ExitCode, "#02 script failure");
712
713                         /*
714                         ar.AsyncWaitHandle.WaitOne (2000, false);
715                         if (bytesRead < "hello".Length)
716                                 Assert.Fail ("#03 got {0} bytes", bytesRead);
717                         Assert.AreEqual ("hello", Encoding.Default.GetString (buffer, 0, 5), "#04");
718                         */
719                 }
720                 
721                 void Read (IAsyncResult ar)
722                 {
723                         Stream stm = (Stream) ar.AsyncState;
724                         bytesRead = stm.EndRead (ar);
725                 }
726
727                 static bool RunningOnUnix {
728                         get {
729                                 int p = (int)Environment.OSVersion.Platform;
730                                 return ((p == 128) || (p == 4) || (p == 6));
731                         }
732                 }
733
734                 public int bytesRead = -1;
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                         var exited = new ManualResetEventSlim ();
794                         p.Exited += (object sender, EventArgs e) => {
795                                 exitedCalledCounter++;
796                                 Assert.IsTrue (p.HasExited);
797                                 exited.Set ();
798                         };
799
800                         p.EnableRaisingEvents = true;
801
802                         p.Start ();
803                         p.BeginErrorReadLine ();
804                         p.BeginOutputReadLine ();
805                         p.WaitForExit ();
806
807                         exited.Wait (10000);
808                         Assert.AreEqual (1, exitedCalledCounter);
809                         Thread.Sleep (50);
810                         Assert.AreEqual (1, exitedCalledCounter);
811                 }
812
813                 [Test]
814                 [NUnit.Framework.Category ("MobileNotWorking")]
815                 public void TestEnableEventsBeforeExitedEvent ()
816                 {
817                         Process p = new Process ();
818                         
819                         p.StartInfo = GetCrossPlatformStartInfo ();
820                         p.StartInfo.UseShellExecute = false;
821                         p.StartInfo.RedirectStandardOutput = true;
822                         p.StartInfo.RedirectStandardError = true;
823
824                         p.EnableRaisingEvents = true;
825
826                         var exitedCalledCounter = 0;
827                         var exited = new ManualResetEventSlim ();
828                         p.Exited += (object sender, EventArgs e) => {
829                                 exitedCalledCounter++;
830                                 Assert.IsTrue (p.HasExited);
831                                 exited.Set ();
832                         };
833
834                         p.Start ();
835                         p.BeginErrorReadLine ();
836                         p.BeginOutputReadLine ();
837                         p.WaitForExit ();
838
839                         Assert.IsTrue (exited.Wait (10000));
840                         Assert.AreEqual (1, exitedCalledCounter);
841                         Thread.Sleep (50);
842                         Assert.AreEqual (1, exitedCalledCounter);
843                 }
844
845                 [Test]
846                 [NUnit.Framework.Category ("MobileNotWorking")]
847                 public void TestDisableEventsBeforeExitedEvent ()
848                 {
849                         Process p = new Process ();
850                         
851                         p.StartInfo = GetCrossPlatformStartInfo ();
852                         p.StartInfo.UseShellExecute = false;
853                         p.StartInfo.RedirectStandardOutput = true;
854                         p.StartInfo.RedirectStandardError = true;
855
856                         p.EnableRaisingEvents = false;
857
858                         var exitedCalledCounter = 0;
859                         p.Exited += (object sender, EventArgs e) => {
860                                 exitedCalledCounter++;
861                         };
862
863                         p.Start ();
864                         p.BeginErrorReadLine ();
865                         p.BeginOutputReadLine ();
866                         p.WaitForExit ();
867
868                         Assert.AreEqual (0, exitedCalledCounter);
869                 }
870
871                 ProcessStartInfo GetCrossPlatformStartInfo ()
872                 {
873                         if (RunningOnUnix) {
874                                 string path;
875 #if MONODROID
876                                 path = "/system/bin/ls";
877 #else
878                                 path = "/bin/ls";
879 #endif
880                                 return new ProcessStartInfo (path, "/");
881                         } else
882                                 return new ProcessStartInfo ("help", "");
883                 }
884 #endif // MONO_FEATURE_PROCESS_START
885
886                 [Test]
887                 public void ProcessName_NotStarted ()
888                 {
889                         Process p = new Process ();
890                         Exception e = null;
891                         try {
892                                 String.IsNullOrEmpty (p.ProcessName);
893                         } catch (Exception ex) {
894                                 e = ex;
895                         }
896                         
897                         Assert.IsNotNull (e, "ProcessName should raise if process was not started");
898                         
899                         //msg should be "No process is associated with this object"
900                         Assert.AreEqual (e.GetType (), typeof (InvalidOperationException),
901                                          "exception should be IOE, I got: " + e.GetType ().Name);
902                         
903                         Assert.IsNull (e.InnerException, "IOE inner exception should be null");
904                 }
905                 
906 #if MONO_FEATURE_PROCESS_START
907                 [Test]
908                 [NUnit.Framework.Category ("MobileNotWorking")]
909                 public void ProcessName_AfterExit ()
910                 {
911                         Process p = new Process ();
912                         p.StartInfo = GetCrossPlatformStartInfo ();
913                         p.StartInfo.UseShellExecute = false;
914                         p.StartInfo.RedirectStandardOutput = true;
915                         p.StartInfo.RedirectStandardError = true;
916                         p.Start ();
917                         p.BeginErrorReadLine();
918                         p.BeginOutputReadLine();
919                         p.WaitForExit ();
920                         String.IsNullOrEmpty (p.ExitCode + "");
921                         
922                         Exception e = null;
923                         try {
924                                 String.IsNullOrEmpty (p.ProcessName);
925                         } catch (Exception ex) {
926                                 e = ex;
927                         }
928                         
929                         Assert.IsNotNull (e, "ProcessName should raise if process was finished");
930                         
931                         //msg should be "Process has exited, so the requested information is not available"
932                         Assert.AreEqual (e.GetType (), typeof (InvalidOperationException),
933                                          "exception should be IOE, I got: " + e.GetType ().Name);
934                         
935                         Assert.IsNull (e.InnerException, "IOE inner exception should be null");
936                 }
937 #endif // MONO_FEATURE_PROCESS_START
938
939                 [Test]
940                 public void Handle_ThrowsOnNotStarted ()
941                 {
942                         Process p = new Process ();
943                         try {
944                                 var x = p.Handle;
945                                 Assert.Fail ("Handle should throw for unstated procs, but returned " + x);
946                         } catch (InvalidOperationException) {
947                         }
948                 }
949
950                 [Test]
951                 public void HasExitedCurrent () {
952                         Assert.IsFalse (Process.GetCurrentProcess ().HasExited);
953                 }
954
955 #if MONO_FEATURE_PROCESS_START
956                 [Test]
957                 [NUnit.Framework.Category ("MobileNotWorking")]
958                 public void DisposeWithDisposedStreams ()
959                 {
960                         var psi = GetCrossPlatformStartInfo ();
961                         psi.RedirectStandardInput = true;
962                         psi.RedirectStandardOutput = true;
963                         psi.UseShellExecute = false;
964
965                         var p = Process.Start (psi);
966                         p.StandardInput.BaseStream.Dispose ();
967                         p.StandardOutput.BaseStream.Dispose ();
968                         p.Dispose ();
969                 }
970
971                 [Test]
972                 [NUnit.Framework.Category ("MobileNotWorking")]
973                 public void StandardInputWrite ()
974                 {
975                         var psi = GetCrossPlatformStartInfo ();
976                         psi.RedirectStandardInput = true;
977                         psi.RedirectStandardOutput = true;
978                         psi.UseShellExecute = false;
979
980                         using (var p = Process.Start (psi)) {
981                                 for (int i = 0; i < 1024 * 9; ++i)
982                                         p.StandardInput.Write ('x');
983                         }
984                 }
985 #endif // MONO_FEATURE_PROCESS_START
986
987                 [Test]
988                 public void Modules () {
989                         var modules = Process.GetCurrentProcess ().Modules;
990                         foreach (var a in AppDomain.CurrentDomain.GetAssemblies ()) {
991                                 var found = false;
992                                 var name = a.GetName ();
993
994                                 StringBuilder sb = new StringBuilder ();
995                                 sb.AppendFormat ("Could not found: {0} {1}\n", name.Name, name.Version);
996                                 sb.AppendLine ("Looked in assemblies:");
997
998                                 foreach (var o in modules) {
999                                         var m = (ProcessModule) o;
1000
1001                                         sb.AppendFormat ("   {0} {1}.{2}.{3}\n", m.FileName.ToString (),
1002                                                         m.FileVersionInfo.FileMajorPart,
1003                                                         m.FileVersionInfo.FileMinorPart,
1004                                                         m.FileVersionInfo.FileBuildPart);
1005
1006                                         if (!m.FileName.StartsWith ("[In Memory] " + name.Name))
1007                                                 continue;
1008
1009                                         var fv = m.FileVersionInfo;
1010                                         if (fv.FileBuildPart != name.Version.Build ||
1011                                                 fv.FileMinorPart != name.Version.Minor ||
1012                                                 fv.FileMajorPart != name.Version.Major)
1013                                                 continue;
1014
1015                                         found = true;
1016                                 }
1017
1018                                 Assert.IsTrue (found, sb.ToString ());
1019                         }
1020                 }
1021
1022 #if MONO_FEATURE_PROCESS_START
1023                 [Test]
1024                 [NUnit.Framework.Category ("MobileNotWorking")]
1025                 [ExpectedException (typeof (InvalidOperationException))]
1026                 public void TestDoubleBeginOutputReadLine ()
1027                 {
1028                         using (Process p = new Process ()) {
1029                                 p.StartInfo = GetCrossPlatformStartInfo ();
1030                                 p.StartInfo.UseShellExecute = false;
1031                                 p.StartInfo.RedirectStandardOutput = true;
1032                                 p.StartInfo.RedirectStandardError = true;
1033
1034                                 p.Start ();
1035
1036                                 p.BeginOutputReadLine ();
1037                                 p.BeginOutputReadLine ();
1038
1039                                 Assert.Fail ();
1040                         }
1041                 }
1042
1043                 [Test]
1044                 [NUnit.Framework.Category ("MobileNotWorking")]
1045                 [ExpectedException (typeof (InvalidOperationException))]
1046                 public void TestDoubleBeginErrorReadLine ()
1047                 {
1048                         using (Process p = new Process ()) {
1049                                 p.StartInfo = GetCrossPlatformStartInfo ();
1050                                 p.StartInfo.UseShellExecute = false;
1051                                 p.StartInfo.RedirectStandardOutput = true;
1052                                 p.StartInfo.RedirectStandardError = true;
1053
1054                                 p.Start ();
1055
1056                                 p.BeginErrorReadLine ();
1057                                 p.BeginErrorReadLine ();
1058
1059                                 Assert.Fail ();
1060                         }
1061                 }
1062 #endif // MONO_FEATURE_PROCESS_START
1063         }
1064 }