Thread background_wait_for_exit_thread;
ISynchronizeInvoke synchronizingObject;
EventHandler exited_event;
- IntPtr stdout_rd;
- IntPtr stderr_rd;
/* Private constructor called from other methods */
private Process(IntPtr handle, int id) {
}
}
+#if MONO_FEATURE_PROCESS_START
private StreamReader error_stream=null;
bool error_stream_exposed;
start_info = value;
}
}
+#else
+ [Obsolete ("Process.StandardError is not supported on the current platform.", true)]
+ public StreamReader StandardError {
+ get { throw new PlatformNotSupportedException ("Process.StandardError is not supported on the current platform."); }
+ }
+
+ [Obsolete ("Process.StandardInput is not supported on the current platform.", true)]
+ public StreamWriter StandardInput {
+ get { throw new PlatformNotSupportedException ("Process.StandardInput is not supported on the current platform."); }
+ }
+
+ [Obsolete ("Process.StandardOutput is not supported on the current platform.", true)]
+ public StreamReader StandardOutput {
+ get { throw new PlatformNotSupportedException ("Process.StandardOutput is not supported on the current platform."); }
+ }
+
+ [Obsolete ("Process.StartInfo is not supported on the current platform.", true)]
+ public ProcessStartInfo StartInfo {
+ get { throw new PlatformNotSupportedException ("Process.StartInfo is not supported on the current platform."); }
+ set { throw new PlatformNotSupportedException ("Process.StartInfo is not supported on the current platform."); }
+ }
+#endif // MONO_FEATURE_PROCESS_START
/* Returns the process start time in Windows file
* times (ticks from DateTime(1/1/1601 00:00 GMT))
// the process (currently we have none).
}
+#if MONO_FEATURE_PROCESS_START
[MethodImplAttribute(MethodImplOptions.InternalCall)]
private extern static bool ShellExecuteEx_internal(ProcessStartInfo startInfo,
ref ProcInfo proc_info);
if (startInfo.RedirectStandardOutput) {
CreatePipe (out stdout_read, out stdout_write, false);
- process.stdout_rd = stdout_read;
} else {
- process.stdout_rd = IntPtr.Zero;
+ stdout_read = IntPtr.Zero;
stdout_write = MonoIO.ConsoleOutput;
}
if (startInfo.RedirectStandardError) {
CreatePipe (out stderr_read, out stderr_write, false);
- process.stderr_rd = stderr_read;
} else {
- process.stderr_rd = IntPtr.Zero;
+ stderr_read = IntPtr.Zero;
stderr_write = MonoIO.ConsoleError;
}
#else
var stdinEncoding = Console.InputEncoding;
#endif
- process.input_stream = new StreamWriter (new FileStream (new SafeFileHandle (stdin_write, false), FileAccess.Write, 8192, false), stdinEncoding) {
+ process.input_stream = new StreamWriter (new FileStream (stdin_write, FileAccess.Write, true, 8192), stdinEncoding) {
AutoFlush = true
};
}
Encoding stdoutEncoding = startInfo.StandardOutputEncoding ?? Console.Out.Encoding;
- process.output_stream = new StreamReader (new FileStream (new SafeFileHandle (stdout_read, false), FileAccess.Read, 8192, false), stdoutEncoding, true, 8192);
+ process.output_stream = new StreamReader (new FileStream (stdout_read, FileAccess.Read, true, 8192), stdoutEncoding, true);
}
if (startInfo.RedirectStandardError) {
Encoding stderrEncoding = startInfo.StandardErrorEncoding ?? Console.Out.Encoding;
- process.error_stream = new StreamReader (new FileStream (new SafeFileHandle (stderr_read, false), FileAccess.Read, 8192, false), stderrEncoding, true, 8192);
+ process.error_stream = new StreamReader (new FileStream (stderr_read, FileAccess.Read, true, 8192), stderrEncoding, true);
}
process.StartBackgroundWaitForExit ();
psi.UseShellExecute = false;
return Start(psi);
}
+#else
+ [Obsolete ("Process.Start is not supported on the current platform.", true)]
+ public bool Start ()
+ {
+ throw new PlatformNotSupportedException ("Process.Start is not supported on the current platform.");
+ }
+
+ [Obsolete ("Process.Start is not supported on the current platform.", true)]
+ public static Process Start (ProcessStartInfo startInfo)
+ {
+ throw new PlatformNotSupportedException ("Process.Start is not supported on the current platform.");
+ }
+
+ [Obsolete ("Process.Start is not supported on the current platform.", true)]
+ public static Process Start (string fileName)
+ {
+ throw new PlatformNotSupportedException ("Process.Start is not supported on the current platform.");
+ }
+
+ [Obsolete ("Process.Start is not supported on the current platform.", true)]
+ public static Process Start(string fileName, string arguments)
+ {
+ throw new PlatformNotSupportedException ("Process.Start is not supported on the current platform.");
+ }
+
+ [Obsolete ("Process.Start is not supported on the current platform.", true)]
+ public static Process Start(string fileName, string username, SecureString password, string domain)
+ {
+ throw new PlatformNotSupportedException ("Process.Start is not supported on the current platform.");
+ }
+
+ [Obsolete ("Process.Start is not supported on the current platform.", true)]
+ public static Process Start(string fileName, string arguments, string username, SecureString password, string domain)
+ {
+ throw new PlatformNotSupportedException ("Process.Start is not supported on the current platform.");
+ }
+#endif // MONO_FEATURE_PROCESS_START
public override string ToString()
{
if (process_handle == IntPtr.Zero)
throw new InvalidOperationException ("No process is associated with this object.");
- DateTime start = DateTime.UtcNow;
-
if (!WaitForExit_internal (process_handle, ms))
return false;
- if (ms >= 0) {
- ms -= (int) (DateTime.UtcNow - start).TotalMilliseconds;
- if (ms <= 0)
- return false;
- }
-
- if (async_output != null && !async_output.IsCompleted) {
- if (false == async_output.AsyncWaitHandle.WaitOne (ms, false))
- return false; // Timed out
+#if MONO_FEATURE_PROCESS_START
+ if (async_output != null && !async_output.IsCompleted)
+ async_output.AsyncWaitHandle.WaitOne ();
- if (ms >= 0) {
- ms -= (int) (DateTime.UtcNow - start).TotalMilliseconds;
- if (ms <= 0)
- return false;
- }
- }
-
- if (async_error != null && !async_error.IsCompleted) {
- if (false == async_error.AsyncWaitHandle.WaitOne (ms, false))
- return false; // Timed out
-
- if (ms >= 0) {
- ms -= (int) (DateTime.UtcNow - start).TotalMilliseconds;
- if (ms <= 0)
- return false;
- }
- }
+ if (async_error != null && !async_error.IsCompleted)
+ async_error.AsyncWaitHandle.WaitOne ();
+#endif // MONO_FEATURE_PROCESS_START
OnExited ();
cb (this, new DataReceivedEventArgs (str));
}
+#if MONO_FEATURE_PROCESS_START
[Flags]
enum AsyncModes {
NoneYet = 0,
StringBuilder sb = new StringBuilder ();
byte[] buffer = new byte [4096];
- public ProcessAsyncReader (Process process, IntPtr handle, bool err_out)
+ const int ERROR_INVALID_HANDLE = 6;
+
+ public ProcessAsyncReader (Process process, FileStream stream, bool err_out)
: base (null, null)
{
this.process = process;
- this.handle = handle;
- this.stream = new FileStream (handle, FileAccess.Read, false);
+ this.handle = stream.SafeFileHandle.DangerousGetHandle ();
+ this.stream = stream;
this.err_out = err_out;
}
- public void BeginRead ()
+ public void BeginReadLine ()
{
- IOSelector.Add (this.handle, new IOSelectorJob (IOOperation.Read, _ => AddInput (), null));
+ IOSelector.Add (this.handle, new IOSelectorJob (IOOperation.Read, _ => Read (), null));
}
- public void AddInput ()
+ void Read ()
{
int nread = 0;
try {
nread = stream.Read (buffer, 0, buffer.Length);
} catch (ObjectDisposedException) {
+ } catch (IOException ex) {
+ if (ex.HResult != (unchecked((int) 0x80070000) | (int) ERROR_INVALID_HANDLE))
+ throw;
} catch (NotSupportedException) {
if (stream.CanRead)
throw;
Flush (false);
- IOSelector.Add (this.handle, new IOSelectorJob (IOOperation.Read, _ => AddInput (), null));
+ IOSelector.Add (this.handle, new IOSelectorJob (IOOperation.Read, _ => Read (), null));
}
void Flush (bool last)
public void Close ()
{
IOSelector.Remove (handle);
- stream.Close ();
}
internal override void CompleteDisposed ()
async_mode |= AsyncModes.AsyncOutput;
output_canceled = false;
if (async_output == null) {
- async_output = new ProcessAsyncReader (this, stdout_rd, true);
- async_output.BeginRead ();
+ async_output = new ProcessAsyncReader (this, (FileStream) output_stream.BaseStream, true);
+ async_output.BeginReadLine ();
}
}
async_mode |= AsyncModes.AsyncError;
error_canceled = false;
if (async_error == null) {
- async_error = new ProcessAsyncReader (this, stderr_rd, false);
- async_error.BeginRead ();
+ async_error = new ProcessAsyncReader (this, (FileStream) error_stream.BaseStream, false);
+ async_error.BeginReadLine ();
}
}
error_canceled = true;
}
+#else
+ [Obsolete ("Process.BeginOutputReadLine is not supported on the current platform.", true)]
+ public void BeginOutputReadLine ()
+ {
+ throw new PlatformNotSupportedException ("Process.BeginOutputReadLine is not supported on the current platform.");
+ }
+
+ [Obsolete ("Process.BeginOutputReadLine is not supported on the current platform.", true)]
+ public void CancelOutputRead ()
+ {
+ throw new PlatformNotSupportedException ("Process.BeginOutputReadLine is not supported on the current platform.");
+ }
+
+ [Obsolete ("Process.BeginOutputReadLine is not supported on the current platform.", true)]
+ public void BeginErrorReadLine ()
+ {
+ throw new PlatformNotSupportedException ("Process.BeginOutputReadLine is not supported on the current platform.");
+ }
+
+ [Obsolete ("Process.BeginOutputReadLine is not supported on the current platform.", true)]
+ public void CancelErrorRead ()
+ {
+ throw new PlatformNotSupportedException ("Process.BeginOutputReadLine is not supported on the current platform.");
+ }
+#endif // MONO_FEATURE_PROCESS_START
[Category ("Behavior")]
[MonitoringDescription ("Raised when this process exits.")]
// If this is a call to Dispose,
// dispose all managed resources.
if (disposing) {
+#if MONO_FEATURE_PROCESS_START
/* These have open FileStreams on the pipes we are about to close */
if (async_output != null)
async_output.Close ();
error_stream.Close ();
error_stream = null;
}
+#endif // MONO_FEATURE_PROCESS_START
}
// Release unmanaged resources
if (background_wait_for_exit_thread != null)
return;
- Thread t = new Thread (_ => WaitForExit ());
+ Thread t = new Thread (_ => WaitForExit ()) { IsBackground = true };
if (Interlocked.CompareExchange (ref background_wait_for_exit_thread, t, null) == null)
t.Start ();