2002-08-23 Gonzalo Paniagua Javier <gonzalo@ximian.com>
[mono.git] / mcs / class / System / System.Diagnostics / Process.cs
1 //
2 // System.Diagnostics.Process.cs
3 //
4 // Authors:
5 //   Dick Porter (dick@ximian.com)
6 //
7 // (C) 2002 Ximian, Inc.
8 //
9
10 using System;
11 using System.IO;
12 using System.ComponentModel;
13 using System.Runtime.CompilerServices;
14 using System.Runtime.InteropServices;
15
16 namespace System.Diagnostics {
17         public class Process : Component {
18                 [StructLayout(LayoutKind.Sequential)]
19                 private struct ProcInfo {
20                         public IntPtr process_handle;
21                         public IntPtr thread_handle;
22                         public int pid;
23                         public int tid;
24                 };
25                 
26                 IntPtr process_handle;
27                 int pid;
28                 
29                 /* Private constructor called from other methods */
30                 private Process(IntPtr handle, int id) {
31                         process_handle=handle;
32                         pid=id;
33                 }
34                 
35                 [MonoTODO]
36                 public Process() {
37                 }
38
39                 [MonoTODO]
40                 public int BasePriority {
41                         get {
42                                 return(0);
43                         }
44                 }
45
46                 [MonoTODO]
47                 public bool EnableRaisingEvents {
48                         get {
49                                 return(false);
50                         }
51                         set {
52                         }
53                 }
54
55                 [MethodImplAttribute(MethodImplOptions.InternalCall)]
56                 private extern static int ExitCode_internal(IntPtr handle);
57
58                 public int ExitCode {
59                         get {
60                                 return(ExitCode_internal(process_handle));
61                         }
62                 }
63
64                 /* Returns the process start time in Windows file
65                  * times (ticks from DateTime(1/1/1601 00:00 GMT))
66                  */
67                 [MethodImplAttribute(MethodImplOptions.InternalCall)]
68                 private extern static long ExitTime_internal(IntPtr handle);
69                 
70                 public DateTime ExitTime {
71                         get {
72                                 return(DateTime.FromFileTime(ExitTime_internal(process_handle)));
73                         }
74                 }
75
76                 public IntPtr Handle {
77                         get {
78                                 return(process_handle);
79                         }
80                 }
81
82                 [MonoTODO]
83                 public int HandleCount {
84                         get {
85                                 return(0);
86                         }
87                 }
88
89                 [MonoTODO]
90                 public bool HasExited {
91                         get {
92                                 return(false);
93                         }
94                 }
95
96                 public int Id {
97                         get {
98                                 return(pid);
99                         }
100                 }
101
102                 [MonoTODO]
103                 public string MachineName {
104                         get {
105                                 return("localhost");
106                         }
107                 }
108
109                 public ProcessModule MainModule {
110                         get {
111                                 return(this.Modules[0]);
112                         }
113                 }
114
115                 [MonoTODO]
116                 public IntPtr MainWindowHandle {
117                         get {
118                                 return((IntPtr)0);
119                         }
120                 }
121
122                 [MonoTODO]
123                 public string MainWindowTitle {
124                         get {
125                                 return("null");
126                         }
127                 }
128
129                 [MonoTODO]
130                 public IntPtr MaxWorkingSet {
131                         get {
132                                 return((IntPtr)0);
133                         }
134                         set {
135                         }
136                 }
137
138                 [MonoTODO]
139                 public IntPtr MinWorkingSet {
140                         get {
141                                 return((IntPtr)0);
142                         }
143                         set {
144                         }
145                 }
146
147                 /* Returns the list of process modules.  The main module is
148                  * element 0.
149                  */
150                 [MethodImplAttribute(MethodImplOptions.InternalCall)]
151                 private extern ProcessModule[] GetModules_internal();
152
153                 private ProcessModuleCollection module_collection;
154                 
155                 public ProcessModuleCollection Modules {
156                         get {
157                                 if(module_collection==null) {
158                                         module_collection=new ProcessModuleCollection(GetModules_internal());
159                                 }
160
161                                 return(module_collection);
162                         }
163                 }
164
165                 [MonoTODO]
166                 public int NonpagedSystemMemorySize {
167                         get {
168                                 return(0);
169                         }
170                 }
171
172                 [MonoTODO]
173                 public int PagedMemorySize {
174                         get {
175                                 return(0);
176                         }
177                 }
178
179                 [MonoTODO]
180                 public int PagedSystemMemorySize {
181                         get {
182                                 return(0);
183                         }
184                 }
185
186                 [MonoTODO]
187                 public int PeakPagedMemorySize {
188                         get {
189                                 return(0);
190                         }
191                 }
192
193                 [MonoTODO]
194                 public int PeakVirtualMemorySize {
195                         get {
196                                 return(0);
197                         }
198                 }
199
200                 [MonoTODO]
201                 public int PeakWorkingSet {
202                         get {
203                                 return(0);
204                         }
205                 }
206
207                 [MonoTODO]
208                 public bool PriorityBoostEnabled {
209                         get {
210                                 return(false);
211                         }
212                         set {
213                         }
214                 }
215
216                 [MonoTODO]
217                 public ProcessPriorityClass PriorityClass {
218                         get {
219                                 return(ProcessPriorityClass.Normal);
220                         }
221                         set {
222                         }
223                 }
224
225                 [MonoTODO]
226                 public int PrivateMemorySize {
227                         get {
228                                 return(0);
229                         }
230                 }
231
232                 [MonoTODO]
233                 public TimeSpan PrivilegedProcessorTime {
234                         get {
235                                 return(new TimeSpan(0));
236                         }
237                 }
238
239                 [MonoTODO]
240                 public string ProcessName {
241                         get {
242                                 return("this-process");
243                         }
244                 }
245
246                 [MonoTODO]
247                 public IntPtr ProcessorAffinity {
248                         get {
249                                 return((IntPtr)0);
250                         }
251                         set {
252                         }
253                 }
254
255                 [MonoTODO]
256                 public bool Responding {
257                         get {
258                                 return(false);
259                         }
260                 }
261
262                 private StreamReader error_stream=null;
263                 
264                 public StreamReader StandardError {
265                         get {
266                                 return(error_stream);
267                         }
268                 }
269
270                 private StreamWriter input_stream=null;
271                 
272                 public StreamWriter StandardInput {
273                         get {
274                                 return(input_stream);
275                         }
276                 }
277
278                 private StreamReader output_stream=null;
279                 
280                 public StreamReader StandardOutput {
281                         get {
282                                 return(output_stream);
283                         }
284                 }
285
286                 private ProcessStartInfo start_info=null;
287                 
288                 public ProcessStartInfo StartInfo {
289                         get {
290                                 if(start_info==null) {
291                                         start_info=new ProcessStartInfo();
292                                 }
293                                 
294                                 return(start_info);
295                         }
296                         set {
297                                 if(value==null) {
298                                         throw new ArgumentException("value is null");
299                                 }
300                                 
301                                 start_info=value;
302                         }
303                 }
304
305                 /* Returns the process start time in Windows file
306                  * times (ticks from DateTime(1/1/1601 00:00 GMT))
307                  */
308                 [MethodImplAttribute(MethodImplOptions.InternalCall)]
309                 private extern static long StartTime_internal(IntPtr handle);
310                 
311                 public DateTime StartTime {
312                         get {
313                                 return(DateTime.FromFileTime(StartTime_internal(process_handle)));
314                         }
315                 }
316
317                 [MonoTODO]
318                 public ISynchronizeInvoke SynchronizingObject {
319                         get {
320                                 return(null);
321                         }
322                         set {
323                         }
324                 }
325
326                 [MonoTODO]
327                 public ProcessThreadCollection Threads {
328                         get {
329                                 return(null);
330                         }
331                 }
332
333                 [MonoTODO]
334                 public TimeSpan TotalProcessorTime {
335                         get {
336                                 return(new TimeSpan(0));
337                         }
338                 }
339
340                 [MonoTODO]
341                 public TimeSpan UserProcessorTime {
342                         get {
343                                 return(new TimeSpan(0));
344                         }
345                 }
346
347                 [MonoTODO]
348                 public int VirtualMemorySize {
349                         get {
350                                 return(0);
351                         }
352                 }
353
354                 [MonoTODO]
355                 public int WorkingSet {
356                         get {
357                                 return(0);
358                         }
359                 }
360
361                 [MonoTODO]
362                 public void Close() {
363                 }
364
365                 [MonoTODO]
366                 public bool CloseMainWindow() {
367                         return(false);
368                 }
369
370                 [MonoTODO]
371                 public static void EnterDebugMode() {
372                 }
373
374                 [MethodImplAttribute(MethodImplOptions.InternalCall)]
375                 private extern static IntPtr GetCurrentProcess_internal();
376                 
377                 [MethodImplAttribute(MethodImplOptions.InternalCall)]
378                 private extern static int GetPid_internal();
379
380                 public static Process GetCurrentProcess() {
381                         return(new Process(GetCurrentProcess_internal(),
382                                            GetPid_internal()));
383                 }
384
385                 [MonoTODO]
386                 public static Process GetProcessById(int processId) {
387                         return(null);
388                 }
389
390                 [MonoTODO]
391                 public static Process GetProcessById(int processId, string machineName) {
392                         return(null);
393                 }
394
395                 [MonoTODO]
396                 public static Process[] GetProcesses() {
397                         return(null);
398                 }
399
400                 [MonoTODO]
401                 public static Process[] GetProcesses(string machineName) {
402                         return(null);
403                 }
404
405                 [MonoTODO]
406                 public static Process[] GetProcessesByName(string processName) {
407                         return(null);
408                 }
409
410                 [MonoTODO]
411                 public static Process[] GetProcessesByName(string processName, string machineName) {
412                         return(null);
413                 }
414
415                 [MonoTODO]
416                 public void Kill() {
417                 }
418
419                 [MonoTODO]
420                 public static void LeaveDebugMode() {
421                 }
422
423                 [MonoTODO]
424                 public void Refresh() {
425                 }
426
427                 [MethodImplAttribute(MethodImplOptions.InternalCall)]
428                 private extern static bool Start_internal(string file,
429                                                           string args,
430                                                           IntPtr stdin,
431                                                           IntPtr stdout,
432                                                           IntPtr stderr,
433                                                           ref ProcInfo proc_info);
434
435                 private static bool Start_common(ProcessStartInfo startInfo,
436                                                  Process process) {
437                         ProcInfo proc_info=new ProcInfo();
438                         IntPtr stdin_rd, stdin_wr;
439                         IntPtr stdout_rd, stdout_wr;
440                         IntPtr stderr_rd, stderr_wr;
441                         bool ret;
442                         
443                         if(startInfo.RedirectStandardInput==true) {
444                                 ret=MonoIO.CreatePipe(out stdin_rd,
445                                                       out stdin_wr);
446                         } else {
447                                 stdin_rd=MonoIO.ConsoleInput;
448                                 /* This is required to stop the
449                                  * &$*£ing stupid compiler moaning
450                                  * that stdin_wr is unassigned, below.
451                                  */
452                                 stdin_wr=(IntPtr)0;
453                         }
454
455                         if(startInfo.RedirectStandardOutput==true) {
456                                 ret=MonoIO.CreatePipe(out stdout_rd,
457                                                       out stdout_wr);
458                         } else {
459                                 stdout_rd=(IntPtr)0;
460                                 stdout_wr=MonoIO.ConsoleOutput;
461                         }
462
463                         if(startInfo.RedirectStandardError==true) {
464                                 ret=MonoIO.CreatePipe(out stderr_rd,
465                                                       out stderr_wr);
466                         } else {
467                                 stderr_rd=(IntPtr)0;
468                                 stderr_wr=MonoIO.ConsoleError;
469                         }
470                         
471                         ret=Start_internal(startInfo.FileName,
472                                            startInfo.Arguments,
473                                            stdin_rd, stdout_wr, stderr_wr,
474                                            ref proc_info);
475
476                         process.process_handle=proc_info.process_handle;
477                         process.pid=proc_info.pid;
478                         
479                         if(startInfo.RedirectStandardInput==true) {
480                                 MonoIO.Close(stdin_rd);
481                                 process.input_stream=new StreamWriter(new FileStream(stdin_wr, FileAccess.Write, true));
482                         }
483
484                         if(startInfo.RedirectStandardOutput==true) {
485                                 MonoIO.Close(stdout_wr);
486                                 process.output_stream=new StreamReader(new FileStream(stdout_rd, FileAccess.Read, true));
487                         }
488
489                         if(startInfo.RedirectStandardError==true) {
490                                 MonoIO.Close(stderr_wr);
491                                 process.error_stream=new StreamReader(new FileStream(stderr_rd, FileAccess.Read, true));
492                         }
493
494                         return(ret);
495                 }
496                 
497                 public bool Start() {
498                         bool ret;
499                         
500                         ret=Start_common(start_info, this);
501                         
502                         return(ret);
503                 }
504
505                 public static Process Start(ProcessStartInfo startInfo) {
506                         Process process=new Process();
507                         bool ret;
508
509                         ret=Start_common(startInfo, process);
510                         
511                         if(ret==true) {
512                                 return(process);
513                         } else {
514                                 return(null);
515                         }
516                 }
517
518                 [MonoTODO]
519                 public static Process Start(string fileName) {
520                         return(null);
521                 }
522
523                 [MonoTODO]
524                 public static Process Start(string fileName, string arguments) {
525                         return(null);
526                 }
527
528                 [MonoTODO]
529                 public override string ToString() {
530                         return("process name");
531                 }
532
533                 /* Waits up to ms milliseconds for process 'handle' to
534                  * exit.  ms can be <0 to mean wait forever.
535                  */
536                 [MethodImplAttribute(MethodImplOptions.InternalCall)]
537                 private extern bool WaitForExit_internal(IntPtr handle,
538                                                          int ms);
539
540                 public void WaitForExit() {
541                         WaitForExit_internal(process_handle, -1);
542                 }
543
544                 public bool WaitForExit(int milliseconds) {
545                         return(WaitForExit_internal(process_handle,
546                                                     milliseconds));
547                 }
548
549                 [MonoTODO]
550                 public bool WaitForInputIdle() {
551                         return(false);
552                 }
553
554                 [MonoTODO]
555                 public bool WaitForInputIdle(int milliseconds) {
556                         return(false);
557                 }
558
559                 [MonoTODO]
560                 public event EventHandler Exited;
561
562                 // Closes the system process handle
563                 [MethodImplAttribute(MethodImplOptions.InternalCall)]
564                 private extern void Process_free_internal(IntPtr handle);
565                 
566                 private bool disposed = false;
567                 
568                 protected override void Dispose(bool disposing) {
569                         // Check to see if Dispose has already been called.
570                         if(this.disposed) {
571                                 // If this is a call to Dispose,
572                                 // dispose all managed resources.
573                                 if(disposing) {
574                                         // Do stuff here
575                                 }
576                                 
577                                 // Release unmanaged resources
578                                 this.disposed=true;
579
580                                 lock(this) {
581                                         if(process_handle!=IntPtr.Zero) {
582                                                 
583                                                 Process_free_internal(process_handle);
584                                                 process_handle=IntPtr.Zero;
585                                         }
586                                 }
587                         }
588                 }
589
590                 public void Dispose() {
591                         Dispose(true);
592                         // Take yourself off the Finalization queue
593                         GC.SuppressFinalize(this);
594                 }
595
596                 [MonoTODO]
597                 protected void OnExited() {
598                 }
599         }
600 }
601