2 // System.Diagnostics.Process.cs
5 // Dick Porter (dick@ximian.com)
6 // Andreas Nahr (ClassDevelopment@A-SoftTech.com)
7 // Gonzalo Paniagua Javier (gonzalo@ximian.com)
9 // (C) 2002 Ximian, Inc.
10 // (C) 2003 Andreas Nahr
11 // (c) 2004,2005,2006 Novell, Inc. (http://www.novell.com)
15 // Permission is hereby granted, free of charge, to any person obtaining
16 // a copy of this software and associated documentation files (the
17 // "Software"), to deal in the Software without restriction, including
18 // without limitation the rights to use, copy, modify, merge, publish,
19 // distribute, sublicense, and/or sell copies of the Software, and to
20 // permit persons to whom the Software is furnished to do so, subject to
21 // the following conditions:
23 // The above copyright notice and this permission notice shall be
24 // included in all copies or substantial portions of the Software.
26 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
27 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
28 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
29 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
30 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
31 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
32 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
37 using System.Collections;
38 using System.ComponentModel;
39 using System.ComponentModel.Design;
40 using System.Runtime.CompilerServices;
41 using System.Runtime.InteropServices;
42 using System.Runtime.Remoting.Messaging;
43 using System.Security.Permissions;
44 using System.Collections.Generic;
45 using System.Security;
46 using System.Threading;
47 using Microsoft.Win32;
48 using Microsoft.Win32.SafeHandles;
50 namespace System.Diagnostics
52 public partial class Process : Component
54 [StructLayout(LayoutKind.Sequential)]
55 private struct ProcInfo
57 public IntPtr process_handle;
58 /* If thread_handle is ever needed for
59 * something, take out the CloseHandle() in
60 * the Start_internal icall in
61 * mono/metadata/process.c
63 public IntPtr thread_handle;
64 public int pid; // Contains -GetLastError () on failure.
66 public string[] envVariables;
67 public string UserName;
69 public IntPtr Password;
70 public bool LoadUserProfile;
75 /* Private constructor called from other methods */
76 private Process (SafeProcessHandle handle, int id) {
77 SetProcessHandle (handle);
82 [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
83 [MonitoringDescription ("Base process priority.")]
84 public int BasePriority {
89 [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
90 [MonitoringDescription ("Handles for this process.")]
91 public int HandleCount {
97 [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden), Browsable (false)]
98 [MonitoringDescription ("The main module of the process.")]
99 public ProcessModule MainModule {
101 return(this.Modules[0]);
106 [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
107 [MonitoringDescription ("The handle of the main window of the process.")]
108 public IntPtr MainWindowHandle {
115 [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
116 [MonitoringDescription ("The title of the main window of the process.")]
117 public string MainWindowTitle {
123 /* Returns the list of process modules. The main module is
126 [MethodImplAttribute(MethodImplOptions.InternalCall)]
127 private extern ProcessModule[] GetModules_internal(IntPtr handle);
129 ProcessModule[] GetModules_internal (SafeProcessHandle handle)
131 bool release = false;
133 handle.DangerousAddRef (ref release);
134 return GetModules_internal (handle.DangerousGetHandle ());
137 handle.DangerousRelease ();
141 [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden), Browsable (false)]
142 [MonitoringDescription ("The modules that are loaded as part of this process.")]
143 public ProcessModuleCollection Modules {
145 if (modules == null) {
146 SafeProcessHandle handle = null;
148 handle = GetProcessHandle (NativeMethods.PROCESS_QUERY_INFORMATION);
149 modules = new ProcessModuleCollection (GetModules_internal (handle));
151 ReleaseProcessHandle (handle);
159 /* data type is from the MonoProcessData enum in mono-proclib.h in the runtime */
160 [MethodImplAttribute(MethodImplOptions.InternalCall)]
161 private extern static long GetProcessData (int pid, int data_type, out int error);
164 [Obsolete ("Use NonpagedSystemMemorySize64")]
165 [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
166 [MonitoringDescription ("The number of bytes that are not pageable.")]
167 public int NonpagedSystemMemorySize {
173 [Obsolete ("Use PagedMemorySize64")]
174 [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
175 [MonitoringDescription ("The number of bytes that are paged.")]
176 public int PagedMemorySize {
178 return(int)PagedMemorySize64;
182 [Obsolete ("Use PagedSystemMemorySize64")]
183 [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
184 [MonitoringDescription ("The amount of paged system memory in bytes.")]
185 public int PagedSystemMemorySize {
187 return(int)PagedMemorySize64;
192 [Obsolete ("Use PeakPagedMemorySize64")]
193 [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
194 [MonitoringDescription ("The maximum amount of paged memory used by this process.")]
195 public int PeakPagedMemorySize {
201 [Obsolete ("Use PeakVirtualMemorySize64")]
202 [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
203 [MonitoringDescription ("The maximum amount of virtual memory used by this process.")]
204 public int PeakVirtualMemorySize {
207 return (int)GetProcessData (processId, 8, out error);
211 [Obsolete ("Use PeakWorkingSet64")]
212 [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
213 [MonitoringDescription ("The maximum amount of system memory used by this process.")]
214 public int PeakWorkingSet {
217 return (int)GetProcessData (processId, 5, out error);
222 [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
223 [MonitoringDescription ("The number of bytes that are not pageable.")]
225 public long NonpagedSystemMemorySize64 {
231 [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
232 [MonitoringDescription ("The number of bytes that are paged.")]
234 public long PagedMemorySize64 {
237 return GetProcessData (processId, 12, out error);
241 [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
242 [MonitoringDescription ("The amount of paged system memory in bytes.")]
244 public long PagedSystemMemorySize64 {
246 return PagedMemorySize64;
251 [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
252 [MonitoringDescription ("The maximum amount of paged memory used by this process.")]
254 public long PeakPagedMemorySize64 {
260 [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
261 [MonitoringDescription ("The maximum amount of virtual memory used by this process.")]
263 public long PeakVirtualMemorySize64 {
266 return GetProcessData (processId, 8, out error);
270 [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
271 [MonitoringDescription ("The maximum amount of system memory used by this process.")]
273 public long PeakWorkingSet64 {
276 return GetProcessData (processId, 5, out error);
281 [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
282 [MonitoringDescription ("Process will be of higher priority while it is actively used.")]
283 public bool PriorityBoostEnabled {
291 [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
292 [MonitoringDescription ("The amount of memory exclusively used by this process.")]
293 [Obsolete ("Use PrivateMemorySize64")]
294 public int PrivateMemorySize {
297 return (int)GetProcessData (processId, 6, out error);
301 [MonoNotSupported ("")]
302 [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
303 [MonitoringDescription ("The session ID for this process.")]
304 public int SessionId {
308 [MethodImplAttribute(MethodImplOptions.InternalCall)]
309 private extern static string ProcessName_internal(IntPtr handle);
311 static string ProcessName_internal(SafeProcessHandle handle)
313 bool release = false;
315 handle.DangerousAddRef (ref release);
316 return ProcessName_internal (handle.DangerousGetHandle ());
319 handle.DangerousRelease ();
323 [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
324 [MonitoringDescription ("The name of this process.")]
325 public string ProcessName {
327 if (process_name == null) {
328 SafeProcessHandle handle = null;
330 handle = GetProcessHandle (NativeMethods.PROCESS_QUERY_INFORMATION);
332 process_name = ProcessName_internal (handle);
334 /* If process_name is _still_ null, assume the process has exited or is inaccessible */
335 if (process_name == null)
336 throw new InvalidOperationException ("Process has exited or is inaccessible, so the requested information is not available.");
338 /* Strip the suffix (if it exists) simplistically instead of removing
339 * any trailing \.???, so we dont get stupid results on sane systems */
340 if(process_name.EndsWith(".exe") || process_name.EndsWith(".bat") || process_name.EndsWith(".com"))
341 process_name = process_name.Substring (0, process_name.Length - 4);
343 ReleaseProcessHandle (handle);
351 [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
352 [MonitoringDescription ("Allowed processor that can be used by this process.")]
353 public IntPtr ProcessorAffinity {
362 [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
363 [MonitoringDescription ("Is this process responsive.")]
364 public bool Responding {
370 #if !MONO_FEATURE_PROCESS_START
371 [Obsolete ("Process.StartInfo is not supported on the current platform.", true)]
372 public ProcessStartInfo StartInfo {
373 get { throw new PlatformNotSupportedException ("Process.StartInfo is not supported on the current platform."); }
374 set { throw new PlatformNotSupportedException ("Process.StartInfo is not supported on the current platform."); }
377 [Obsolete ("Process.StandardError is not supported on the current platform.", true)]
378 public StreamReader StandardError {
379 get { throw new PlatformNotSupportedException ("Process.StandardError is not supported on the current platform."); }
382 [Obsolete ("Process.StandardInput is not supported on the current platform.", true)]
383 public StreamWriter StandardInput {
384 get { throw new PlatformNotSupportedException ("Process.StandardInput is not supported on the current platform."); }
387 [Obsolete ("Process.StandardOutput is not supported on the current platform.", true)]
388 public StreamReader StandardOutput {
389 get { throw new PlatformNotSupportedException ("Process.StandardOutput is not supported on the current platform."); }
391 #endif // !MONO_FEATURE_PROCESS_START
394 [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
395 [MonitoringDescription ("The number of threads of this process.")]
396 public ProcessThreadCollection Threads {
398 if (threads == null) {
400 // This'll return a correctly-sized array of empty ProcessThreads for now.
401 threads = new ProcessThreadCollection(new ProcessThread [GetProcessData (processId, 0, out error)]);
408 [Obsolete ("Use VirtualMemorySize64")]
409 [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
410 [MonitoringDescription ("The amount of virtual memory currently used for this process.")]
411 public int VirtualMemorySize {
414 return (int)GetProcessData (processId, 7, out error);
418 [Obsolete ("Use WorkingSet64")]
419 [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
420 [MonitoringDescription ("The amount of physical memory currently used for this process.")]
421 public int WorkingSet {
424 return (int)GetProcessData (processId, 4, out error);
428 [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
429 [MonitoringDescription ("The amount of memory exclusively used by this process.")]
431 public long PrivateMemorySize64 {
434 return GetProcessData (processId, 6, out error);
438 [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
439 [MonitoringDescription ("The amount of virtual memory currently used for this process.")]
441 public long VirtualMemorySize64 {
444 return GetProcessData (processId, 7, out error);
448 [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
449 [MonitoringDescription ("The amount of physical memory currently used for this process.")]
451 public long WorkingSet64 {
454 return GetProcessData (processId, 4, out error);
458 public bool CloseMainWindow ()
460 SafeProcessHandle handle = null;
462 handle = GetProcessHandle (NativeMethods.PROCESS_TERMINATE);
463 return NativeMethods.TerminateProcess(handle, -2);
465 ReleaseProcessHandle(handle);
469 [MethodImplAttribute(MethodImplOptions.InternalCall)]
470 private extern static IntPtr GetProcess_internal(int pid);
472 [MonoTODO ("There is no support for retrieving process information from a remote machine")]
473 public static Process GetProcessById(int processId, string machineName) {
474 if (machineName == null)
475 throw new ArgumentNullException ("machineName");
477 if (!IsLocalMachine (machineName))
478 throw new NotImplementedException ();
480 IntPtr proc = GetProcess_internal(processId);
482 if (proc == IntPtr.Zero)
483 throw new ArgumentException ("Can't find process with ID " + processId.ToString ());
485 /* The handle returned by GetProcess_internal is owned by its caller, so we must pass true to SafeProcessHandle */
486 return (new Process (new SafeProcessHandle (proc, true), processId));
489 public static Process[] GetProcessesByName(string processName, string machineName)
491 if (machineName == null)
492 throw new ArgumentNullException ("machineName");
494 if (!IsLocalMachine (machineName))
495 throw new NotImplementedException ();
497 Process[] processes = GetProcesses ();
498 if (processes.Length == 0)
503 for (int i = 0; i < processes.Length; i++) {
505 if (String.Compare (processName, processes[i].ProcessName, true) == 0)
506 processes [size++] = processes[i];
507 } catch (SystemException) {
508 /* The process might exit between GetProcesses_internal and GetProcessById */
512 Array.Resize<Process> (ref processes, size);
517 [MethodImplAttribute(MethodImplOptions.InternalCall)]
518 private extern static int[] GetProcesses_internal();
520 [MonoTODO ("There is no support for retrieving process information from a remote machine")]
521 public static Process[] GetProcesses(string machineName) {
522 if (machineName == null)
523 throw new ArgumentNullException ("machineName");
525 if (!IsLocalMachine (machineName))
526 throw new NotImplementedException ();
528 int [] pids = GetProcesses_internal ();
530 return new Process [0];
532 var proclist = new List<Process> (pids.Length);
533 for (int i = 0; i < pids.Length; i++) {
535 proclist.Add (GetProcessById (pids [i]));
536 } catch (SystemException) {
537 /* The process might exit
539 * GetProcesses_internal and
545 return proclist.ToArray ();
548 private static bool IsLocalMachine (string machineName)
550 if (machineName == "." || machineName.Length == 0)
553 return (string.Compare (machineName, Environment.MachineName, true) == 0);
556 #if MONO_FEATURE_PROCESS_START
557 [MethodImplAttribute(MethodImplOptions.InternalCall)]
558 private extern static bool ShellExecuteEx_internal(ProcessStartInfo startInfo, ref ProcInfo procInfo);
560 [MethodImplAttribute(MethodImplOptions.InternalCall)]
561 private extern static bool CreateProcess_internal(ProcessStartInfo startInfo, IntPtr stdin, IntPtr stdout, IntPtr stderr, ref ProcInfo procInfo);
563 bool StartWithShellExecuteEx (ProcessStartInfo startInfo)
566 throw new ObjectDisposedException (GetType ().Name);
568 if (!String.IsNullOrEmpty(startInfo.UserName) || (startInfo.Password != null))
569 throw new InvalidOperationException(SR.GetString(SR.CantStartAsUser));
571 if (startInfo.RedirectStandardInput || startInfo.RedirectStandardOutput || startInfo.RedirectStandardError)
572 throw new InvalidOperationException(SR.GetString(SR.CantRedirectStreams));
574 if (startInfo.StandardErrorEncoding != null)
575 throw new InvalidOperationException(SR.GetString(SR.StandardErrorEncodingNotAllowed));
577 if (startInfo.StandardOutputEncoding != null)
578 throw new InvalidOperationException(SR.GetString(SR.StandardOutputEncodingNotAllowed));
580 // can't set env vars with ShellExecuteEx...
581 if (startInfo.environmentVariables != null)
582 throw new InvalidOperationException(SR.GetString(SR.CantUseEnvVars));
584 ProcInfo procInfo = new ProcInfo();
587 FillUserInfo (startInfo, ref procInfo);
589 ret = ShellExecuteEx_internal (startInfo, ref procInfo);
591 if (procInfo.Password != IntPtr.Zero)
592 Marshal.ZeroFreeBSTR (procInfo.Password);
593 procInfo.Password = IntPtr.Zero;
596 throw new Win32Exception (-procInfo.pid);
599 SetProcessHandle (new SafeProcessHandle (procInfo.process_handle, true));
600 SetProcessId (procInfo.pid);
606 // Creates a pipe with read and write descriptors
608 static void CreatePipe (out IntPtr read, out IntPtr write, bool writeDirection)
613 // Creates read/write pipe from parent -> child perspective
614 // a child process uses same descriptors after fork. That's
615 // 4 descriptors in total where only 2. One in child, one in parent
616 // should be active and the other 2 closed. Which ones depends on
617 // comunication direction
619 // parent --------> child (parent can write, child can read)
621 // read: closed read: used
622 // write: used write: closed
625 // parent <-------- child (parent can read, child can write)
627 // read: used read: closed
628 // write: closed write: used
630 // It can still be tricky for predefined descriptiors http://unixwiz.net/techtips/remap-pipe-fds.html
632 if (!MonoIO.CreatePipe (out read, out write, out error))
633 throw MonoIO.GetException (error);
636 const int DUPLICATE_SAME_ACCESS = 0x00000002;
637 var tmp = writeDirection ? write : read;
639 if (!MonoIO.DuplicateHandle (Process.GetCurrentProcess ().Handle, tmp, Process.GetCurrentProcess ().Handle, out tmp, 0, 0, DUPLICATE_SAME_ACCESS, out error))
640 throw MonoIO.GetException (error);
642 if (writeDirection) {
643 if (!MonoIO.Close (write, out error))
644 throw MonoIO.GetException (error);
647 if (!MonoIO.Close (read, out error))
648 throw MonoIO.GetException (error);
654 static bool IsWindows
658 PlatformID platform = Environment.OSVersion.Platform;
659 if (platform == PlatformID.Win32S ||
660 platform == PlatformID.Win32Windows ||
661 platform == PlatformID.Win32NT ||
662 platform == PlatformID.WinCE) {
669 bool StartWithCreateProcess (ProcessStartInfo startInfo)
671 if (startInfo.StandardOutputEncoding != null && !startInfo.RedirectStandardOutput)
672 throw new InvalidOperationException (SR.GetString(SR.StandardOutputEncodingNotAllowed));
674 if (startInfo.StandardErrorEncoding != null && !startInfo.RedirectStandardError)
675 throw new InvalidOperationException (SR.GetString(SR.StandardErrorEncodingNotAllowed));
678 throw new ObjectDisposedException (GetType ().Name);
680 var procInfo = new ProcInfo ();
682 if (startInfo.HaveEnvVars) {
683 List<string> envVariables = null;
684 StringBuilder sb = null;
686 foreach (DictionaryEntry de in startInfo.EnvironmentVariables) {
687 if (de.Value == null)
690 if (envVariables == null)
691 envVariables = new List<string> ();
694 sb = new StringBuilder ();
698 sb.Append ((string) de.Key);
700 sb.Append ((string) de.Value);
702 envVariables.Add (sb.ToString ());
705 procInfo.envVariables = envVariables?.ToArray ();
709 IntPtr stdin_read = IntPtr.Zero, stdin_write = IntPtr.Zero;
710 IntPtr stdout_read = IntPtr.Zero, stdout_write = IntPtr.Zero;
711 IntPtr stderr_read = IntPtr.Zero, stderr_write = IntPtr.Zero;
714 if (startInfo.RedirectStandardInput) {
715 CreatePipe (out stdin_read, out stdin_write, true);
717 stdin_read = MonoIO.ConsoleInput;
718 stdin_write = IntPtr.Zero;
721 if (startInfo.RedirectStandardOutput) {
722 CreatePipe (out stdout_read, out stdout_write, false);
724 stdout_read = IntPtr.Zero;
725 stdout_write = MonoIO.ConsoleOutput;
728 if (startInfo.RedirectStandardError) {
729 CreatePipe (out stderr_read, out stderr_write, false);
731 stderr_read = IntPtr.Zero;
732 stderr_write = MonoIO.ConsoleError;
735 FillUserInfo (startInfo, ref procInfo);
738 // FIXME: For redirected pipes we need to send descriptors of
739 // stdin_write, stdout_read, stderr_read to child process and
740 // close them there (fork makes exact copy of parent's descriptors)
742 if (!CreateProcess_internal (startInfo, stdin_read, stdout_write, stderr_write, ref procInfo)) {
743 throw new Win32Exception (-procInfo.pid, "ApplicationName='" + startInfo.FileName + "', CommandLine='" + startInfo.Arguments +
744 "', CurrentDirectory='" + startInfo.WorkingDirectory + "', Native error= " + Win32Exception.GetErrorMessage (-procInfo.pid));
747 if (startInfo.RedirectStandardInput) {
748 if (stdin_read != IntPtr.Zero)
749 MonoIO.Close (stdin_read, out error);
750 if (stdin_write != IntPtr.Zero)
751 MonoIO.Close (stdin_write, out error);
754 if (startInfo.RedirectStandardOutput) {
755 if (stdout_read != IntPtr.Zero)
756 MonoIO.Close (stdout_read, out error);
757 if (stdout_write != IntPtr.Zero)
758 MonoIO.Close (stdout_write, out error);
761 if (startInfo.RedirectStandardError) {
762 if (stderr_read != IntPtr.Zero)
763 MonoIO.Close (stderr_read, out error);
764 if (stderr_write != IntPtr.Zero)
765 MonoIO.Close (stderr_write, out error);
770 if (procInfo.Password != IntPtr.Zero) {
771 Marshal.ZeroFreeBSTR (procInfo.Password);
772 procInfo.Password = IntPtr.Zero;
776 SetProcessHandle (new SafeProcessHandle (procInfo.process_handle, true));
777 SetProcessId (procInfo.pid);
779 #pragma warning disable 618
781 if (startInfo.RedirectStandardInput) {
782 MonoIO.Close (stdin_read, out error);
785 var stdinEncoding = Encoding.Default;
787 var stdinEncoding = Console.InputEncoding;
789 standardInput = new StreamWriter (new FileStream (stdin_write, FileAccess.Write, true, 8192), stdinEncoding) {
794 if (startInfo.RedirectStandardOutput) {
795 MonoIO.Close (stdout_write, out error);
797 Encoding stdoutEncoding = startInfo.StandardOutputEncoding ?? Console.Out.Encoding;
799 standardOutput = new StreamReader (new FileStream (stdout_read, FileAccess.Read, true, 8192), stdoutEncoding, true);
802 if (startInfo.RedirectStandardError) {
803 MonoIO.Close (stderr_write, out error);
805 Encoding stderrEncoding = startInfo.StandardErrorEncoding ?? Console.Out.Encoding;
807 standardError = new StreamReader (new FileStream (stderr_read, FileAccess.Read, true, 8192), stderrEncoding, true);
809 #pragma warning restore
814 // Note that ProcInfo.Password must be freed.
815 private static void FillUserInfo (ProcessStartInfo startInfo, ref ProcInfo procInfo)
817 if (startInfo.UserName.Length != 0) {
818 procInfo.UserName = startInfo.UserName;
819 procInfo.Domain = startInfo.Domain;
820 if (startInfo.Password != null)
821 procInfo.Password = Marshal.SecureStringToBSTR (startInfo.Password);
823 procInfo.Password = IntPtr.Zero;
824 procInfo.LoadUserProfile = startInfo.LoadUserProfile;
828 [Obsolete ("Process.Start is not supported on the current platform.", true)]
831 throw new PlatformNotSupportedException ("Process.Start is not supported on the current platform.");
834 [Obsolete ("Process.Start is not supported on the current platform.", true)]
835 public static Process Start (ProcessStartInfo startInfo)
837 throw new PlatformNotSupportedException ("Process.Start is not supported on the current platform.");
840 [Obsolete ("Process.Start is not supported on the current platform.", true)]
841 public static Process Start (string fileName)
843 throw new PlatformNotSupportedException ("Process.Start is not supported on the current platform.");
846 [Obsolete ("Process.Start is not supported on the current platform.", true)]
847 public static Process Start(string fileName, string arguments)
849 throw new PlatformNotSupportedException ("Process.Start is not supported on the current platform.");
852 [Obsolete ("Process.Start is not supported on the current platform.", true)]
853 public static Process Start(string fileName, string userName, SecureString password, string domain)
855 throw new PlatformNotSupportedException ("Process.Start is not supported on the current platform.");
858 [Obsolete ("Process.Start is not supported on the current platform.", true)]
859 public static Process Start(string fileName, string arguments, string userName, SecureString password, string domain)
861 throw new PlatformNotSupportedException ("Process.Start is not supported on the current platform.");
863 #endif // MONO_FEATURE_PROCESS_START
865 #if !MONO_FEATURE_PROCESS_START
866 [Obsolete ("Process.BeginOutputReadLine is not supported on the current platform.", true)]
867 public void BeginOutputReadLine ()
869 throw new PlatformNotSupportedException ("Process.BeginOutputReadLine is not supported on the current platform.");
872 [Obsolete ("Process.BeginOutputReadLine is not supported on the current platform.", true)]
873 public void CancelOutputRead ()
875 throw new PlatformNotSupportedException ("Process.BeginOutputReadLine is not supported on the current platform.");
878 [Obsolete ("Process.BeginOutputReadLine is not supported on the current platform.", true)]
879 public void BeginErrorReadLine ()
881 throw new PlatformNotSupportedException ("Process.BeginOutputReadLine is not supported on the current platform.");
884 [Obsolete ("Process.BeginOutputReadLine is not supported on the current platform.", true)]
885 public void CancelErrorRead ()
887 throw new PlatformNotSupportedException ("Process.BeginOutputReadLine is not supported on the current platform.");
889 #endif // !MONO_FEATURE_PROCESS_START
892 /// Raise the Exited event, but make sure we don't do it more than once.
895 void RaiseOnExited() {
898 if (!raisedOnExited) {
900 if (!raisedOnExited) {
901 raisedOnExited = true;