Process.cs 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819
  1. //
  2. // System.Diagnostics.Process.cs
  3. //
  4. // Authors:
  5. // Dick Porter ([email protected])
  6. // Andreas Nahr ([email protected])
  7. //
  8. // (C) 2002 Ximian, Inc.
  9. // (C) 2003 Andreas Nahr
  10. //
  11. using System;
  12. using System.IO;
  13. using System.ComponentModel;
  14. using System.ComponentModel.Design;
  15. using System.Runtime.CompilerServices;
  16. using System.Runtime.InteropServices;
  17. using System.Collections;
  18. namespace System.Diagnostics {
  19. [DefaultEvent ("Exited"), DefaultProperty ("StartInfo")]
  20. [Designer ("System.Diagnostics.Design.ProcessDesigner, " + Consts.AssemblySystem_Design, typeof (IDesigner))]
  21. public class Process : Component
  22. {
  23. [StructLayout(LayoutKind.Sequential)]
  24. private struct ProcInfo
  25. {
  26. public IntPtr process_handle;
  27. public IntPtr thread_handle;
  28. public int pid;
  29. public int tid;
  30. };
  31. IntPtr process_handle;
  32. int pid;
  33. /* Private constructor called from other methods */
  34. private Process(IntPtr handle, int id) {
  35. process_handle=handle;
  36. pid=id;
  37. }
  38. [MonoTODO]
  39. public Process() {
  40. }
  41. [MonoTODO]
  42. [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
  43. [MonitoringDescription ("Base process priority.")]
  44. public int BasePriority {
  45. get {
  46. return(0);
  47. }
  48. }
  49. [MonoTODO]
  50. [DefaultValue (false), Browsable (false)]
  51. [MonitoringDescription ("Check for exiting of the process to raise the apropriate event.")]
  52. public bool EnableRaisingEvents {
  53. get {
  54. return(false);
  55. }
  56. set {
  57. }
  58. }
  59. [MethodImplAttribute(MethodImplOptions.InternalCall)]
  60. private extern static int ExitCode_internal(IntPtr handle);
  61. [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden), Browsable (false)]
  62. [MonitoringDescription ("The exit code of the process.")]
  63. public int ExitCode {
  64. get {
  65. return(ExitCode_internal(process_handle));
  66. }
  67. }
  68. /* Returns the process start time in Windows file
  69. * times (ticks from DateTime(1/1/1601 00:00 GMT))
  70. */
  71. [MethodImplAttribute(MethodImplOptions.InternalCall)]
  72. private extern static long ExitTime_internal(IntPtr handle);
  73. [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden), Browsable (false)]
  74. [MonitoringDescription ("The exit time of the process.")]
  75. public DateTime ExitTime {
  76. get {
  77. return(DateTime.FromFileTime(ExitTime_internal(process_handle)));
  78. }
  79. }
  80. [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden), Browsable (false)]
  81. [MonitoringDescription ("Handle for this process.")]
  82. public IntPtr Handle {
  83. get {
  84. return(process_handle);
  85. }
  86. }
  87. [MonoTODO]
  88. [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
  89. [MonitoringDescription ("Handles for this process.")]
  90. public int HandleCount {
  91. get {
  92. return(0);
  93. }
  94. }
  95. [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden), Browsable (false)]
  96. [MonitoringDescription ("Determines if the process is still running.")]
  97. public bool HasExited {
  98. get {
  99. int exitcode=ExitCode;
  100. if(exitcode==259) {
  101. /* STILL_ACTIVE */
  102. return(false);
  103. } else {
  104. return(true);
  105. }
  106. }
  107. }
  108. [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
  109. [MonitoringDescription ("Process identifier.")]
  110. public int Id {
  111. get {
  112. return(pid);
  113. }
  114. }
  115. [MonoTODO]
  116. [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden), Browsable (false)]
  117. [MonitoringDescription ("The name of the computer running the process.")]
  118. public string MachineName {
  119. get {
  120. return("localhost");
  121. }
  122. }
  123. [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden), Browsable (false)]
  124. [MonitoringDescription ("The main module of the process.")]
  125. public ProcessModule MainModule {
  126. get {
  127. return(this.Modules[0]);
  128. }
  129. }
  130. [MonoTODO]
  131. [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
  132. [MonitoringDescription ("The handle of the main window of the process.")]
  133. public IntPtr MainWindowHandle {
  134. get {
  135. return((IntPtr)0);
  136. }
  137. }
  138. [MonoTODO]
  139. [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
  140. [MonitoringDescription ("The title of the main window of the process.")]
  141. public string MainWindowTitle {
  142. get {
  143. return("null");
  144. }
  145. }
  146. [MethodImplAttribute(MethodImplOptions.InternalCall)]
  147. private extern static bool GetWorkingSet_internal(IntPtr handle, out int min, out int max);
  148. [MethodImplAttribute(MethodImplOptions.InternalCall)]
  149. private extern static bool SetWorkingSet_internal(IntPtr handle, int min, int max, bool use_min);
  150. /* LAMESPEC: why is this an IntPtr not a plain int? */
  151. [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
  152. [MonitoringDescription ("The maximum working set for this process.")]
  153. public IntPtr MaxWorkingSet {
  154. get {
  155. if(HasExited) {
  156. throw new InvalidOperationException("The process " + ProcessName + " (ID " + Id + ") has exited");
  157. }
  158. int min;
  159. int max;
  160. bool ok=GetWorkingSet_internal(process_handle, out min, out max);
  161. if(ok==false) {
  162. throw new Win32Exception();
  163. }
  164. return((IntPtr)max);
  165. }
  166. set {
  167. if(HasExited) {
  168. throw new InvalidOperationException("The process " + ProcessName + " (ID " + Id + ") has exited");
  169. }
  170. bool ok=SetWorkingSet_internal(process_handle, 0, value.ToInt32(), false);
  171. if(ok==false) {
  172. throw new Win32Exception();
  173. }
  174. }
  175. }
  176. [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
  177. [MonitoringDescription ("The minimum working set for this process.")]
  178. public IntPtr MinWorkingSet {
  179. get {
  180. if(HasExited) {
  181. throw new InvalidOperationException("The process " + ProcessName + " (ID " + Id + ") has exited");
  182. }
  183. int min;
  184. int max;
  185. bool ok=GetWorkingSet_internal(process_handle, out min, out max);
  186. if(ok==false) {
  187. throw new Win32Exception();
  188. }
  189. return((IntPtr)min);
  190. }
  191. set {
  192. if(HasExited) {
  193. throw new InvalidOperationException("The process " + ProcessName + " (ID " + Id + ") has exited");
  194. }
  195. bool ok=SetWorkingSet_internal(process_handle, value.ToInt32(), 0, true);
  196. if(ok==false) {
  197. throw new Win32Exception();
  198. }
  199. }
  200. }
  201. /* Returns the list of process modules. The main module is
  202. * element 0.
  203. */
  204. [MethodImplAttribute(MethodImplOptions.InternalCall)]
  205. private extern ProcessModule[] GetModules_internal();
  206. private ProcessModuleCollection module_collection;
  207. [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden), Browsable (false)]
  208. [MonitoringDescription ("The modules that are loaded as part of this process.")]
  209. public ProcessModuleCollection Modules {
  210. get {
  211. if(module_collection==null) {
  212. module_collection=new ProcessModuleCollection(GetModules_internal());
  213. }
  214. return(module_collection);
  215. }
  216. }
  217. [MonoTODO]
  218. [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
  219. [MonitoringDescription ("The number of bytes that are not pageable.")]
  220. public int NonpagedSystemMemorySize {
  221. get {
  222. return(0);
  223. }
  224. }
  225. [MonoTODO]
  226. [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
  227. [MonitoringDescription ("The number of bytes that are paged.")]
  228. public int PagedMemorySize {
  229. get {
  230. return(0);
  231. }
  232. }
  233. [MonoTODO]
  234. [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
  235. [MonitoringDescription ("The amount of paged system memory in bytes.")]
  236. public int PagedSystemMemorySize {
  237. get {
  238. return(0);
  239. }
  240. }
  241. [MonoTODO]
  242. [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
  243. [MonitoringDescription ("The maximum amount of paged memory used by this process.")]
  244. public int PeakPagedMemorySize {
  245. get {
  246. return(0);
  247. }
  248. }
  249. [MonoTODO]
  250. [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
  251. [MonitoringDescription ("The maximum amount of virtual memory used by this process.")]
  252. public int PeakVirtualMemorySize {
  253. get {
  254. return(0);
  255. }
  256. }
  257. [MonoTODO]
  258. [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
  259. [MonitoringDescription ("The maximum amount of system memory used by this process.")]
  260. public int PeakWorkingSet {
  261. get {
  262. return(0);
  263. }
  264. }
  265. [MonoTODO]
  266. [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
  267. [MonitoringDescription ("Process will be of higher priority while it is actively used.")]
  268. public bool PriorityBoostEnabled {
  269. get {
  270. return(false);
  271. }
  272. set {
  273. }
  274. }
  275. [MonoTODO]
  276. [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
  277. [MonitoringDescription ("The relative process priority.")]
  278. public ProcessPriorityClass PriorityClass {
  279. get {
  280. return(ProcessPriorityClass.Normal);
  281. }
  282. set {
  283. }
  284. }
  285. [MonoTODO]
  286. [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
  287. [MonitoringDescription ("The amount of memory exclusively used by this process.")]
  288. public int PrivateMemorySize {
  289. get {
  290. return(0);
  291. }
  292. }
  293. [MonoTODO]
  294. [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
  295. [MonitoringDescription ("The amount of processing time spent is the OS core for this process.")]
  296. public TimeSpan PrivilegedProcessorTime {
  297. get {
  298. return(new TimeSpan(0));
  299. }
  300. }
  301. [MethodImplAttribute(MethodImplOptions.InternalCall)]
  302. private extern static string ProcessName_internal(IntPtr handle);
  303. private string process_name=null;
  304. [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
  305. [MonitoringDescription ("The name of this process.")]
  306. public string ProcessName {
  307. get {
  308. if(process_name==null) {
  309. process_name=ProcessName_internal(process_handle);
  310. /* If process_name is _still_
  311. * null, assume the process
  312. * has exited
  313. */
  314. if(process_name==null) {
  315. throw new SystemException("The process has exited");
  316. }
  317. /* Strip the suffix (if it
  318. * exists) simplistically
  319. * instead of removing any
  320. * trailing \.???, so we dont
  321. * get stupid results on sane
  322. * systems
  323. */
  324. if(process_name.EndsWith(".exe") ||
  325. process_name.EndsWith(".bat") ||
  326. process_name.EndsWith(".com")) {
  327. process_name=process_name.Substring(0, process_name.Length-4);
  328. }
  329. }
  330. return(process_name);
  331. }
  332. }
  333. [MonoTODO]
  334. [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
  335. [MonitoringDescription ("Allowed processor that can be used by this process.")]
  336. public IntPtr ProcessorAffinity {
  337. get {
  338. return((IntPtr)0);
  339. }
  340. set {
  341. }
  342. }
  343. [MonoTODO]
  344. [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
  345. [MonitoringDescription ("Is this process responsive.")]
  346. public bool Responding {
  347. get {
  348. return(false);
  349. }
  350. }
  351. private StreamReader error_stream=null;
  352. [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden), Browsable (false)]
  353. [MonitoringDescription ("The standard error stream of this process.")]
  354. public StreamReader StandardError {
  355. get {
  356. return(error_stream);
  357. }
  358. }
  359. private StreamWriter input_stream=null;
  360. [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden), Browsable (false)]
  361. [MonitoringDescription ("The standard input stream of this process.")]
  362. public StreamWriter StandardInput {
  363. get {
  364. return(input_stream);
  365. }
  366. }
  367. private StreamReader output_stream=null;
  368. [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden), Browsable (false)]
  369. [MonitoringDescription ("The standard output stream of this process.")]
  370. public StreamReader StandardOutput {
  371. get {
  372. return(output_stream);
  373. }
  374. }
  375. private ProcessStartInfo start_info=null;
  376. [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden), Browsable (false)]
  377. [MonitoringDescription ("Information for the start of this process.")]
  378. public ProcessStartInfo StartInfo {
  379. get {
  380. if(start_info==null) {
  381. start_info=new ProcessStartInfo();
  382. }
  383. return(start_info);
  384. }
  385. set {
  386. if(value==null) {
  387. throw new ArgumentException("value is null");
  388. }
  389. start_info=value;
  390. }
  391. }
  392. /* Returns the process start time in Windows file
  393. * times (ticks from DateTime(1/1/1601 00:00 GMT))
  394. */
  395. [MethodImplAttribute(MethodImplOptions.InternalCall)]
  396. private extern static long StartTime_internal(IntPtr handle);
  397. [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
  398. [MonitoringDescription ("The time this process started.")]
  399. public DateTime StartTime {
  400. get {
  401. return(DateTime.FromFileTime(StartTime_internal(process_handle)));
  402. }
  403. }
  404. [MonoTODO]
  405. [DefaultValue (null), Browsable (false)]
  406. [MonitoringDescription ("The object that is used to synchronize event handler calls for this process.")]
  407. public ISynchronizeInvoke SynchronizingObject {
  408. get {
  409. return(null);
  410. }
  411. set {
  412. }
  413. }
  414. [MonoTODO]
  415. [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden), Browsable (false)]
  416. [MonitoringDescription ("The number of threads of this process.")]
  417. public ProcessThreadCollection Threads {
  418. get {
  419. return(null);
  420. }
  421. }
  422. [MonoTODO]
  423. [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
  424. [MonitoringDescription ("The total CPU time spent for this process.")]
  425. public TimeSpan TotalProcessorTime {
  426. get {
  427. return(new TimeSpan(0));
  428. }
  429. }
  430. [MonoTODO]
  431. [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
  432. [MonitoringDescription ("The CPU time spent for this process in user mode.")]
  433. public TimeSpan UserProcessorTime {
  434. get {
  435. return(new TimeSpan(0));
  436. }
  437. }
  438. [MonoTODO]
  439. [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
  440. [MonitoringDescription ("The amount of virtual memory currently used for this process.")]
  441. public int VirtualMemorySize {
  442. get {
  443. return(0);
  444. }
  445. }
  446. [MonoTODO]
  447. [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
  448. [MonitoringDescription ("The amount of physical memory currently used for this process.")]
  449. public int WorkingSet {
  450. get {
  451. return(0);
  452. }
  453. }
  454. [MonoTODO]
  455. public void Close() {
  456. }
  457. [MonoTODO]
  458. public bool CloseMainWindow() {
  459. return(false);
  460. }
  461. [MonoTODO]
  462. public static void EnterDebugMode() {
  463. }
  464. [MethodImplAttribute(MethodImplOptions.InternalCall)]
  465. private extern static IntPtr GetProcess_internal(int pid);
  466. [MethodImplAttribute(MethodImplOptions.InternalCall)]
  467. private extern static int GetPid_internal();
  468. public static Process GetCurrentProcess() {
  469. int pid=GetPid_internal();
  470. IntPtr proc=GetProcess_internal(pid);
  471. if(proc==IntPtr.Zero) {
  472. throw new SystemException("Can't find current process");
  473. }
  474. return(new Process(proc, pid));
  475. }
  476. public static Process GetProcessById(int processId) {
  477. IntPtr proc=GetProcess_internal(processId);
  478. if(proc==IntPtr.Zero) {
  479. throw new ArgumentException("Can't find process with ID " + processId.ToString());
  480. }
  481. return(new Process(proc, processId));
  482. }
  483. [MonoTODO]
  484. public static Process GetProcessById(int processId, string machineName) {
  485. throw new NotImplementedException();
  486. }
  487. [MethodImplAttribute(MethodImplOptions.InternalCall)]
  488. private extern static int[] GetProcesses_internal();
  489. public static Process[] GetProcesses() {
  490. int[] pids=GetProcesses_internal();
  491. ArrayList proclist=new ArrayList();
  492. for(int i=0; i<pids.Length; i++) {
  493. try {
  494. proclist.Add(GetProcessById(pids[i]));
  495. } catch (SystemException) {
  496. /* The process might exit
  497. * between
  498. * GetProcesses_internal and
  499. * GetProcessById
  500. */
  501. }
  502. }
  503. return((Process[])proclist.ToArray(typeof(Process)));
  504. }
  505. [MonoTODO]
  506. public static Process[] GetProcesses(string machineName) {
  507. throw new NotImplementedException();
  508. }
  509. public static Process[] GetProcessesByName(string processName) {
  510. Process[] procs=GetProcesses();
  511. ArrayList proclist=new ArrayList();
  512. for(int i=0; i<procs.Length; i++) {
  513. /* Ignore case */
  514. if(String.Compare(processName,
  515. procs[i].ProcessName,
  516. true)==0) {
  517. proclist.Add(procs[i]);
  518. }
  519. }
  520. return((Process[])proclist.ToArray(typeof(Process)));
  521. }
  522. [MonoTODO]
  523. public static Process[] GetProcessesByName(string processName, string machineName) {
  524. throw new NotImplementedException();
  525. }
  526. [MonoTODO]
  527. public void Kill() {
  528. }
  529. [MonoTODO]
  530. public static void LeaveDebugMode() {
  531. }
  532. [MonoTODO]
  533. public void Refresh() {
  534. }
  535. [MethodImplAttribute(MethodImplOptions.InternalCall)]
  536. private extern static bool Start_internal(string cmd,
  537. string dir,
  538. IntPtr stdin,
  539. IntPtr stdout,
  540. IntPtr stderr,
  541. ref ProcInfo proc_info);
  542. private static bool Start_common(ProcessStartInfo startInfo,
  543. Process process) {
  544. ProcInfo proc_info=new ProcInfo();
  545. IntPtr stdin_rd, stdin_wr;
  546. IntPtr stdout_rd, stdout_wr;
  547. IntPtr stderr_rd, stderr_wr;
  548. bool ret;
  549. if(startInfo.FileName == "") {
  550. throw new InvalidOperationException("File name has not been set");
  551. }
  552. if(startInfo.RedirectStandardInput==true) {
  553. ret=MonoIO.CreatePipe(out stdin_rd,
  554. out stdin_wr);
  555. } else {
  556. stdin_rd=MonoIO.ConsoleInput;
  557. /* This is required to stop the
  558. * &$*£ing stupid compiler moaning
  559. * that stdin_wr is unassigned, below.
  560. */
  561. stdin_wr=(IntPtr)0;
  562. }
  563. if(startInfo.RedirectStandardOutput==true) {
  564. ret=MonoIO.CreatePipe(out stdout_rd,
  565. out stdout_wr);
  566. } else {
  567. stdout_rd=(IntPtr)0;
  568. stdout_wr=MonoIO.ConsoleOutput;
  569. }
  570. if(startInfo.RedirectStandardError==true) {
  571. ret=MonoIO.CreatePipe(out stderr_rd,
  572. out stderr_wr);
  573. } else {
  574. stderr_rd=(IntPtr)0;
  575. stderr_wr=MonoIO.ConsoleError;
  576. }
  577. ret=Start_internal(startInfo.FileName + " " +
  578. startInfo.Arguments,
  579. startInfo.WorkingDirectory,
  580. stdin_rd, stdout_wr, stderr_wr,
  581. ref proc_info);
  582. MonoIOError error;
  583. if (!ret) {
  584. if (startInfo.RedirectStandardInput == true)
  585. MonoIO.Close (stdin_rd, out error);
  586. if (startInfo.RedirectStandardOutput == true)
  587. MonoIO.Close (stdout_wr, out error);
  588. if (startInfo.RedirectStandardError == true)
  589. MonoIO.Close (stderr_wr, out error);
  590. throw new Win32Exception ();
  591. }
  592. process.process_handle=proc_info.process_handle;
  593. process.pid=proc_info.pid;
  594. if(startInfo.RedirectStandardInput==true) {
  595. MonoIO.Close(stdin_rd, out error);
  596. process.input_stream=new StreamWriter(new FileStream(stdin_wr, FileAccess.Write, true));
  597. process.input_stream.AutoFlush=true;
  598. }
  599. if(startInfo.RedirectStandardOutput==true) {
  600. MonoIO.Close(stdout_wr, out error);
  601. process.output_stream=new StreamReader(new FileStream(stdout_rd, FileAccess.Read, true));
  602. }
  603. if(startInfo.RedirectStandardError==true) {
  604. MonoIO.Close(stderr_wr, out error);
  605. process.error_stream=new StreamReader(new FileStream(stderr_rd, FileAccess.Read, true));
  606. }
  607. return(ret);
  608. }
  609. public bool Start() {
  610. bool ret;
  611. ret=Start_common(start_info, this);
  612. return(ret);
  613. }
  614. public static Process Start(ProcessStartInfo startInfo) {
  615. Process process=new Process();
  616. bool ret;
  617. ret=Start_common(startInfo, process);
  618. if(ret==true) {
  619. return(process);
  620. } else {
  621. return(null);
  622. }
  623. }
  624. public static Process Start(string fileName) {
  625. return Start(new ProcessStartInfo(fileName));
  626. }
  627. public static Process Start(string fileName,
  628. string arguments) {
  629. return Start(new ProcessStartInfo(fileName, arguments));
  630. }
  631. public override string ToString() {
  632. return(base.ToString() +
  633. " (" + this.ProcessName + ")");
  634. }
  635. /* Waits up to ms milliseconds for process 'handle' to
  636. * exit. ms can be <0 to mean wait forever.
  637. */
  638. [MethodImplAttribute(MethodImplOptions.InternalCall)]
  639. private extern bool WaitForExit_internal(IntPtr handle,
  640. int ms);
  641. public void WaitForExit() {
  642. WaitForExit_internal(process_handle, -1);
  643. }
  644. public bool WaitForExit(int milliseconds) {
  645. return(WaitForExit_internal(process_handle,
  646. milliseconds));
  647. }
  648. [MonoTODO]
  649. public bool WaitForInputIdle() {
  650. return(false);
  651. }
  652. [MonoTODO]
  653. public bool WaitForInputIdle(int milliseconds) {
  654. return(false);
  655. }
  656. [Category ()]
  657. [MonitoringDescription ("Raised when this process exits.")]
  658. public event EventHandler Exited;
  659. // Closes the system process handle
  660. [MethodImplAttribute(MethodImplOptions.InternalCall)]
  661. private extern void Process_free_internal(IntPtr handle);
  662. private bool disposed = false;
  663. protected override void Dispose(bool disposing) {
  664. // Check to see if Dispose has already been called.
  665. if(this.disposed) {
  666. this.disposed=true;
  667. // If this is a call to Dispose,
  668. // dispose all managed resources.
  669. if(disposing) {
  670. // Do stuff here
  671. }
  672. // Release unmanaged resources
  673. lock(this) {
  674. if(process_handle!=IntPtr.Zero) {
  675. Process_free_internal(process_handle);
  676. process_handle=IntPtr.Zero;
  677. }
  678. }
  679. }
  680. base.Dispose (disposing);
  681. }
  682. protected void OnExited()
  683. {
  684. if (Exited != null)
  685. Exited (this, EventArgs.Empty);
  686. }
  687. }
  688. }