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