ProcessTest.cs 32 KB

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