Exemple #1
0
        public async Task Start(Connection connection, ElevationRequest request)
        {
            if (Settings.SecurityEnforceUacIsolation)
            {
                throw new NotSupportedException("VT Mode not supported when SecurityEnforceUacIsolation=true");
            }

            int? exitCode;
            Task t1 = null, t2 = null, t3 = null;

            _connection = connection;
            System.Diagnostics.Process runningProcess = null;
            try
            {
                string command = request.FileName + " " + request.Arguments;
                using (var inputPipe = new PseudoConsolePipe())
                    using (var outputPipe = new PseudoConsolePipe())
                    {
                        using (var pseudoConsole = PseudoConsole.PseudoConsole.Create(inputPipe.ReadSide, outputPipe.WriteSide, (short)request.ConsoleWidth, (short)request.ConsoleHeight))
                        {
                            using (var process = StartPseudoConsole(command, PseudoConsole.PseudoConsole.PseudoConsoleThreadAttribute, pseudoConsole.Handle, request.StartFolder))
                            {
                                runningProcess = System.Diagnostics.Process.GetProcessById(process.ProcessInfo.dwProcessId);

                                // copy all pseudoconsole output to stdout
                                t1 = Task.Run(() => CopyPipeToOutput(outputPipe.ReadSide));
                                // prompt for stdin input and send the result to the pseudoconsole
                                t2 = Task.Run(() => CopyInputToPipe(inputPipe.WriteSide));
                                // discard Control stream
                                t3 = new StreamReader(_connection.ControlStream, Settings.Encoding).ConsumeOutput((s) => Task.CompletedTask);

                                Logger.Instance.Log($"Process ({process.ProcessInfo.dwProcessId}) started: {request.FileName} {request.Arguments}", LogLevel.Debug);
                                // free resources in case the console is ungracefully closed (e.g. by the 'x' in the window titlebar)
                                // var t3 = new StreamReader(pipe, Globals.Encoding).ConsumeOutput((s) => WriteToStdInput(s, process));

                                OnClose(() => DisposeResources(process, pseudoConsole, outputPipe, inputPipe));

                                WaitHandle.WaitAny(new WaitHandle[] { runningProcess.GetProcessWaitHandle(), connection.DisconnectedWaitHandle });

                                exitCode = process.GetExitCode();
                            }
                        }
                    }

                if (connection.IsAlive)
                {
                    await connection.ControlStream.WriteAsync($"{Constants.TOKEN_EXITCODE}{exitCode ?? 0}{Constants.TOKEN_EXITCODE}").ConfigureAwait(false);
                }

                await connection.FlushAndCloseAll().ConfigureAwait(false);
            }
            catch (Exception ex)
            {
                Logger.Instance.Log(ex.ToString(), LogLevel.Error);
                await connection.ControlStream.WriteAsync($"{Constants.TOKEN_ERROR}Server Error: {ex.ToString()}\r\n{Constants.TOKEN_ERROR}").ConfigureAwait(false);

                await connection.FlushAndCloseAll().ConfigureAwait(false);

                return;
            }
            finally
            {
                if (runningProcess != null && !runningProcess.HasExited)
                {
                    runningProcess.Terminate();
                }
            }
        }