Ejemplo n.º 1
0
 public static SilentProcess StartConsoleProcessSilently(string exepath, string arguments, RedirectDataReceivedHandler stdoutHandler, RedirectDataReceivedHandler stderrHandler)
 {
     return(StartConsoleProcessSilentlyImpl(exepath, arguments, stdoutHandler, stderrHandler, false));
 }
Ejemplo n.º 2
0
        private static SilentProcess StartConsoleProcessSilentlyImpl(string exepath, string arguments, RedirectDataReceivedHandler stdoutHandler, RedirectDataReceivedHandler stderrHandler, bool combineStdoutAndStderr)
        {
            bool redirectstdout = false;
            bool redirectstderr = false;

            if (stdoutHandler != null)
            {
                redirectstdout = true;
            }
            if (stderrHandler != null && !combineStdoutAndStderr)
            {
                redirectstderr = true;
            }
            if (RunningOnWindows())
            {
                //There is a bug in the System.Diagnostics.Process class that makes it
                //do this incorrectly, so we need to supply the correct implementation

                //Pipes for I/O Redirection
                IntPtr StdoutReadPipe  = IntPtr.Zero;
                IntPtr StdoutWritePipe = IntPtr.Zero;
                IntPtr StderrReadPipe  = IntPtr.Zero;
                IntPtr StderrWritePipe = IntPtr.Zero;

                STARTUPINFO         StartInfo = new STARTUPINFO();
                PROCESS_INFORMATION ProcessInfo;

                if (redirectstdout)
                {
                    //Fill in the fields of the SecurityAttribitutes structure to pass in to CreatePipe
                    SECURITY_ATTRIBUTES SecurityAttributes = new SECURITY_ATTRIBUTES();
                    SecurityAttributes.nLength              = Marshal.SizeOf(SecurityAttributes);
                    SecurityAttributes.bInheritHandle       = TRUE;
                    SecurityAttributes.lpSecurityDescriptor = IntPtr.Zero;

                    //Create the Pipe
                    CreatePipeNetEx(out StdoutReadPipe, out StdoutWritePipe, ref SecurityAttributes, 0);

                    //Ensure the read handle is not inherited
                    try
                    {
                        SetHandleInformationNetEx(StdoutReadPipe, HANDLE_FLAGS.INHERIT, (HANDLE_FLAGS)0);
                    }
                    catch
                    {
                        CloseHandleNetEx(StdoutReadPipe);
                        CloseHandleNetEx(StdoutWritePipe);
                        throw;
                    }
                }
                try
                {
                    if (redirectstderr)
                    {
                        //Fill in the fields of the SecurityAttribitutes structure to pass in to CreatePipe
                        SECURITY_ATTRIBUTES SecurityAttributes = new SECURITY_ATTRIBUTES();
                        SecurityAttributes.nLength              = Marshal.SizeOf(SecurityAttributes);
                        SecurityAttributes.bInheritHandle       = TRUE;
                        SecurityAttributes.lpSecurityDescriptor = IntPtr.Zero;

                        //Create the pipe
                        CreatePipeNetEx(out StderrReadPipe, out StderrWritePipe, ref SecurityAttributes, 0);

                        //Ensure the read handle is not inherited
                        try
                        {
                            SetHandleInformationNetEx(StderrReadPipe, HANDLE_FLAGS.INHERIT, (HANDLE_FLAGS)0);
                        }
                        catch
                        {
                            CloseHandleNetEx(StderrReadPipe);
                            CloseHandleNetEx(StderrWritePipe);
                            throw;
                        }
                    }
                    try
                    {
                        //Fill in the fields of the StartInfo structure to pass in to CreateProcess
                        StartInfo.cb          = Marshal.SizeOf(StartInfo);
                        StartInfo.dwFlags     = STARTF_USESHOWWINDOW;
                        StartInfo.wShowWindow = SW_HIDE;

                        if (redirectstderr || redirectstdout)
                        {
                            StartInfo.dwFlags   |= STARTF_USESTDHANDLES;
                            StartInfo.hStdError  = IntPtr.Zero;
                            StartInfo.hStdInput  = IntPtr.Zero;
                            StartInfo.hStdOutput = IntPtr.Zero;
                        }
                        if (redirectstdout)
                        {
                            StartInfo.hStdOutput = StdoutWritePipe;
                            if (combineStdoutAndStderr)
                            {
                                StartInfo.hStdError = StdoutWritePipe;
                            }
                        }
                        if (redirectstderr)
                        {
                            StartInfo.hStdError = StderrWritePipe;
                        }

                        //Call CreateProcess
                        if (redirectstderr || redirectstdout)
                        {
                            if (!CreateProcess(null, string.Format("\"{0}\" {1}", exepath, arguments),
                                               IntPtr.Zero, IntPtr.Zero, true, CREATE_NEW_CONSOLE, IntPtr.Zero, null, ref StartInfo, out ProcessInfo))
                            {
                                throw new Win32Exception(Marshal.GetLastWin32Error());
                            }
                        }
                        else
                        {
                            if (!CreateProcess(null, string.Format("\"{0}\" {1}", exepath, arguments),
                                               IntPtr.Zero, IntPtr.Zero, false, CREATE_NEW_CONSOLE, IntPtr.Zero, null, ref StartInfo, out ProcessInfo))
                            {
                                throw new Win32Exception(Marshal.GetLastWin32Error());
                            }
                        }

                        //Close the Handles
                        //
                        CloseHandleNetEx(ProcessInfo.hThread);

                        //Create the redirection threads
                        if (redirectstdout)
                        {
                            RedirectReadLoop stdoutLoop = new RedirectReadLoop();
                            stdoutLoop.RedirectedPipe = StdoutReadPipe;
                            stdoutLoop.handler        = stdoutHandler;

                            //The child has its own handle for the write side of the pipe
                            //so we should close ours so the pipe will "break" when the child
                            //shuts down, giving us indication to stop the read loop.
                            CloseHandleNetEx(StdoutWritePipe);

                            Thread t = new Thread(new ThreadStart(stdoutLoop.ReadLoop));
                            t.Start();
                        }
                        if (redirectstderr)
                        {
                            RedirectReadLoop stderrLoop = new RedirectReadLoop();
                            stderrLoop.RedirectedPipe = StderrReadPipe;
                            stderrLoop.handler        = stderrHandler;

                            //The child has its own handle for the write side of the pipe
                            //so we should close ours so the pipe will "break" when the child
                            //shuts down, giving us indication to stop the read loop.
                            CloseHandleNetEx(StderrWritePipe);

                            Thread t = new Thread(new ThreadStart(stderrLoop.ReadLoop));
                            t.Start();
                        }
                        return(new SilentProcess(ProcessInfo.hProcess, null));
                    }
                    catch
                    {
                        if (redirectstderr)
                        {
                            CloseHandleNetEx(StderrReadPipe);
                            CloseHandleNetEx(StderrWritePipe);
                        }
                        throw;
                    }
                }
                catch
                {
                    if (redirectstdout)
                    {
                        CloseHandleNetEx(StdoutReadPipe);
                        CloseHandleNetEx(StdoutWritePipe);
                    }
                    throw;
                }
            }
            else
            {
                //On UNIX we can use the built in implementation
                ProcessStartInfo info = new ProcessStartInfo(exepath, arguments);
                info.CreateNoWindow  = true;
                info.WindowStyle     = ProcessWindowStyle.Hidden;
                info.UseShellExecute = false;
                Process process = new Process();
                DataReceivedEventHandlerWrapper stdoutWrapper = null;
                DataReceivedEventHandlerWrapper stderrWrapper = null;

                if (redirectstdout)
                {
                    info.RedirectStandardOutput = true;
                    stdoutWrapper         = new DataReceivedEventHandlerWrapper();
                    stdoutWrapper.wrapped = stdoutHandler;
                    DataReceivedEventHandler handler = new DataReceivedEventHandler(stdoutWrapper.Handle);

                    process.OutputDataReceived += handler;
                    if (combineStdoutAndStderr)
                    {
                        info.RedirectStandardError = true;
                        process.ErrorDataReceived += handler;
                    }
                }
                if (redirectstderr)
                {
                    info.RedirectStandardError = true;
                    stderrWrapper         = new DataReceivedEventHandlerWrapper();
                    stderrWrapper.wrapped = stderrHandler;
                    DataReceivedEventHandler handler = new DataReceivedEventHandler(stderrWrapper.Handle);

                    process.ErrorDataReceived += handler;
                }
                process.StartInfo = info;
                process.Start();
                if (redirectstdout)
                {
                    process.BeginOutputReadLine();
                }
                if (redirectstderr || (redirectstdout && combineStdoutAndStderr))
                {
                    process.BeginErrorReadLine();
                }

                return(new SilentProcess(IntPtr.Zero, process));
            }
        }
Ejemplo n.º 3
0
 public static SilentProcess StartConsoleProcessSilently(string exepath, string arguments, RedirectDataReceivedHandler outputHandler)
 {
     return(StartConsoleProcessSilentlyImpl(exepath, arguments, outputHandler, null, true));
 }