예제 #1
0
        public ExecInstance(ExecOptions options)
        {
            try
            {
                this.InputEncoding  = Console.OutputEncoding;
                this.OutputEncoding = this.ErrorEncoding = Console.InputEncoding;

                this.Options = options._NullCheck();

                ProcessStartInfo info = new ProcessStartInfo()
                {
                    FileName               = options.FileName,
                    UseShellExecute        = false,
                    RedirectStandardOutput = true,
                    RedirectStandardError  = true,
                    RedirectStandardInput  = true,
                    CreateNoWindow         = true,
                    WorkingDirectory       = options.CurrentDirectory._NullIfEmpty() !,
                };

                if (this.Options.AdditionalEnvVars != null)
                {
                    foreach (var kv in this.Options.AdditionalEnvVars)
                    {
                        if (kv.Key._IsFilled() && kv.Value._IsFilled())
                        {
                            info.EnvironmentVariables.Add(kv.Key, kv.Value);
                        }
                    }
                }

                if (options.ArgumentsList != null)
                {
                    options.ArgumentsList._DoForEach(a => info.ArgumentList.Add(a._NonNull()));
                }
                else
                {
                    info.Arguments = options.Arguments._NullIfZeroLen() !;
                }

                StartTick = Time.HighResTick64;

                Proc = Process.Start(info) !;

                Proc._FixProcessObjectHandleLeak(); // メモリリーク解消

                this.ProcessId = Proc.Id;

                // 標準入出力を接続する
                this.StandardPipePoint_MySide = PipePoint.NewDuplexPipeAndGetOneSide(PipePointSide.A_LowerSide);
                this._InputOutputPipePoint    = this.StandardPipePoint_MySide.CounterPart._NullCheck();
                this.StandardPipeWrapper      = new PipePointStreamWrapper(StandardPipePoint_MySide, Proc.StandardOutput.BaseStream, Proc.StandardInput.BaseStream);

                // 標準エラー出力を接続する
                this.ErrorPipePoint_MySide = PipePoint.NewDuplexPipeAndGetOneSide(PipePointSide.A_LowerSide);
                this._ErrorPipePoint       = this.ErrorPipePoint_MySide.CounterPart._NullCheck();
                this.ErrorPipeWrapper      = new PipePointStreamWrapper(ErrorPipePoint_MySide, Proc.StandardError.BaseStream, Stream.Null);

                if (options.Flags.Bit(ExecFlags.EasyInputOutputMode))
                {
                    this.EasyInputOutputStub   = this._InputOutputPipePoint.GetNetAppProtocolStub(noCheckDisconnected: true);
                    this.EasyInputOutputStream = this.EasyInputOutputStub.GetStream();

                    this.EasyErrorStub   = this._ErrorPipePoint.GetNetAppProtocolStub(noCheckDisconnected: true);
                    this.EasyErrorStream = this.EasyErrorStub.GetStream();

                    if (options.EasyInputStr != null && options.EasyInputStr.Length >= 1)
                    {
                        // 標準入力の注入タスク
                        this.EasyInputTask = this.EasyInputOutputStream.SendAsync(this.Options.EasyInputStr !._GetBytes(this.InputEncoding), this.GrandCancel)._LeakCheck();
                    }

                    // 標準出力の読み出しタスク
                    this.EasyOutputTask = this.EasyInputOutputStream._ReadWithMaxBufferSizeAsync(this.Options.EasyOutputMaxSize, this.GrandCancel,
                                                                                                 async(data, cancel) => await EasyPrintRealTimeRecvDataCallbackAsync(data, false, cancel))._LeakCheck();

                    // 標準エラー出力の読み出しタスク
                    this.EasyErrorTask = this.EasyErrorStream._ReadWithMaxBufferSizeAsync(this.Options.EasyOutputMaxSize, this.GrandCancel,
                                                                                          async(data, cancel) => await EasyPrintRealTimeRecvDataCallbackAsync(data, true, cancel))._LeakCheck();

                    // リアルタイムバッファ監視タスク
                    if (Options.EasyRealtimeRecvBufCallbackAsync != null)
                    {
                        this.EasyRealtimeBufferMainteTask = EasyRealtimeBufferMainteTaskAsync(this.GrandCancel)._LeakCheck();
                    }
                }

                this.StartMainLoop(MainLoopAsync);
            }
            catch
            {
                this._DisposeSafe();
                throw;
            }
        }
예제 #2
0
        public ExecInstance(ExecOptions options)
        {
            try
            {
                this.InputEncoding  = Console.OutputEncoding;
                this.OutputEncoding = this.ErrorEncoding = Console.InputEncoding;

                this.Options = options._NullCheck();

                ProcessStartInfo info = new ProcessStartInfo()
                {
                    FileName               = options.FileName,
                    UseShellExecute        = false,
                    RedirectStandardOutput = true,
                    RedirectStandardError  = true,
                    RedirectStandardInput  = true,
                    CreateNoWindow         = true,
                    WorkingDirectory       = options.CurrentDirectory._NullIfEmpty(),
                };

                if (options.ArgumentsList != null)
                {
                    options.ArgumentsList._DoForEach(a => info.ArgumentList.Add(a._NonNull()));
                }
                else
                {
                    info.Arguments = options.Arguments._NullIfZeroLen();
                }

                StartTick = Time.HighResTick64;

                Proc = Process.Start(info);

                this.ProcessId = Proc.Id;

                // 標準入出力を接続する
                this.StandardPipePoint_MySide = PipePoint.NewDuplexPipeAndGetOneSide(PipePointSide.A_LowerSide);
                this._InputOutputPipePoint    = this.StandardPipePoint_MySide.CounterPart._NullCheck();
                this.StandardPipeWrapper      = new PipePointStreamWrapper(StandardPipePoint_MySide, Proc.StandardOutput.BaseStream, Proc.StandardInput.BaseStream);

                // 標準エラー出力を接続する
                this.ErrorPipePoint_MySide = PipePoint.NewDuplexPipeAndGetOneSide(PipePointSide.A_LowerSide);
                this._ErrorPipePoint       = this.ErrorPipePoint_MySide.CounterPart._NullCheck();
                this.ErrorPipeWrapper      = new PipePointStreamWrapper(ErrorPipePoint_MySide, Proc.StandardError.BaseStream, Stream.Null);

                if (options.Flags.Bit(ExecFlags.EasyInputOutputMode))
                {
                    this.EasyInputOutputStub   = this._InputOutputPipePoint.GetNetAppProtocolStub(noCheckDisconnected: true);
                    this.EasyInputOutputStream = this.EasyInputOutputStub.GetStream();

                    this.EasyErrorStub   = this._ErrorPipePoint.GetNetAppProtocolStub(noCheckDisconnected: true);
                    this.EasyErrorStream = this.EasyErrorStub.GetStream();

                    if (options.EasyInputStr != null)
                    {
                        // 標準入力の注入タスク
                        this.EasyInputTask = this.EasyInputOutputStream.SendAsync(this.Options.EasyInputStr !._GetBytes(this.InputEncoding), this.GrandCancel)._LeakCheck();
                    }

                    // 標準出力の読み出しタスク
                    this.EasyOutputTask = this.EasyInputOutputStream._ReadWithMaxBufferSizeAsync(this.Options.EasyOutputMaxSize, this.GrandCancel)._LeakCheck();

                    // 標準エラー出力の読み出しタスク
                    this.EasyErrorTask = this.EasyErrorStream._ReadWithMaxBufferSizeAsync(this.Options.EasyOutputMaxSize, this.GrandCancel)._LeakCheck();
                }

                this.StartMainLoop(MainLoopAsync);
            }
            catch
            {
                this._DisposeSafe();
                throw;
            }
        }