EnderAlice

I/O Proxy Test

Aug 26th, 2014
345
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Diagnostics;
  4. using System.IO;
  5. using System.Linq;
  6. using System.Text;
  7. using System.Threading;
  8. using System.Threading.Tasks;
  9.  
  10. namespace IOProxy
  11. {
  12.     internal class AsyncIO
  13.     {
  14.         protected static readonly TaskFactory MyTaskFactory = new TaskFactory();
  15.         protected Task MyTask;
  16.         protected CancellationTokenSource CancelToken;
  17.         protected TextReader Reader;
  18.         protected TextWriter Writer;
  19.  
  20.         public AsyncIO(TextReader Reader, TextWriter Writer)
  21.         {
  22.             this.Reader = Reader;
  23.             this.Writer = Writer;
  24.         }
  25.  
  26.         public void StartAsyncTask()
  27.         {
  28.             this.CancelToken = new CancellationTokenSource();
  29.             this.MyTask = Task.Run(() => this.AsyncTask(), this.CancelToken.Token);
  30.         }
  31.  
  32.         private void AsyncTask()
  33.         {
  34.             for(;;)
  35.             {
  36.                 try
  37.                 {
  38.                     var OneChar = this.Reader.Read();
  39.                     this.Writer.Write((char)OneChar);
  40.                     Debug.WriteLine("Input {0}", (uint)OneChar);
  41.                 }
  42.                 catch(Exception)
  43.                 {
  44.                 }
  45.             }
  46.         }
  47.  
  48.         public void Cancel()
  49.         {
  50.             try
  51.             {
  52.                 CancelToken.Cancel();
  53.                 //this.MyTask.Wait();
  54.             }
  55.             catch(AggregateException)
  56.             {
  57.             }
  58.  
  59.             this.CancelToken = null;
  60.             this.MyTask = null;
  61.         }
  62.     }
  63.  
  64.     class Program
  65.     {
  66.         static void Main(string[] args)
  67.         {
  68.             Console.Out.WriteLine("© 2014 alice");
  69.             if(args.Length < 1)
  70.             {
  71.                 Console.Out.WriteLine("No program name to execute.");
  72.                 return;
  73.             }
  74.  
  75.             // 引数はすべて子プロセスに渡す
  76.             var ChildProcess = new Process();
  77.             var Arguments = new string[args.Length - 1];
  78.             Array.Copy(args, 1, Arguments, 0, Arguments.Length);
  79.  
  80.             for(int i = 0; i < Arguments.Length; i++)
  81.             {
  82.                 if(Arguments[i].Contains(" "))
  83.                 {
  84.                     Arguments[i] = "\"" + Arguments[i] + "\"";
  85.                 }
  86.             }
  87.  
  88.             ChildProcess.StartInfo.FileName = args[0];
  89.             ChildProcess.StartInfo.Arguments = string.Join(" ", Arguments);
  90.             ChildProcess.StartInfo.UseShellExecute = false;
  91.  
  92.             // 標準入出力ハンドルをこのプロセスから引き継がせるようにする
  93.             ChildProcess.StartInfo.RedirectStandardInput = true;
  94.             ChildProcess.StartInfo.RedirectStandardOutput = true;
  95.             ChildProcess.StartInfo.RedirectStandardError = true;
  96.  
  97.             // 子プロセスの出力(こちらでの読み込む時に)をUTF-8として解釈するように指定する
  98.             ChildProcess.StartInfo.StandardErrorEncoding = Encoding.UTF8;
  99.             ChildProcess.StartInfo.StandardOutputEncoding = Encoding.UTF8;
  100.  
  101.             ChildProcess.OutputDataReceived += ChildProcess_OutputDataReceived;
  102.             ChildProcess.ErrorDataReceived += ChildProcess_ErrorDataReceived;
  103.  
  104.             try
  105.             {
  106.                 ChildProcess.Start();
  107.             }
  108.             catch(Exception e)
  109.             {
  110.                 Console.Out.WriteLine("Exception {0}!", e);
  111.                 ChildProcess = null;
  112.             }
  113.  
  114.             if(ChildProcess == null)
  115.             {
  116.                 return;
  117.             }
  118.  
  119.             ChildProcess.BeginErrorReadLine();
  120.             ChildProcess.BeginOutputReadLine();
  121.  
  122.             //var AsyncStdOut = new AsyncIO(ChildProcess.StandardOutput, Console.Out);
  123.             //var AsyncStdErr = new AsyncIO(ChildProcess.StandardError, Console.Error);
  124.             var AsyncStdIn = new AsyncIO(Console.In, ChildProcess.StandardInput);
  125.             //ChildProcess.StandardInput.Encoding = Encoding.UTF8;
  126.  
  127.             //AsyncStdOut.StartAsyncTask();
  128.             //AsyncStdErr.StartAsyncTask();
  129.             AsyncStdIn.StartAsyncTask();
  130.  
  131.             ChildProcess.WaitForExit();
  132.  
  133.             //AsyncStdOut.Cancel();
  134.             //AsyncStdErr.Cancel();
  135.             AsyncStdIn.Cancel();
  136.  
  137.             //ChildProcess.StandardError.Close();
  138.             //ChildProcess.StandardOutput.Close();
  139.             ChildProcess.StandardInput.Close();
  140.         }
  141.  
  142.         static void ChildProcess_ErrorDataReceived(object sender, DataReceivedEventArgs e)
  143.         {
  144.             Console.Error.WriteLine(e.Data);
  145.         }
  146.  
  147.         static void ChildProcess_OutputDataReceived(object sender, DataReceivedEventArgs e)
  148.         {
  149.             Console.Out.WriteLine(e.Data);
  150.         }
  151.     }
  152. }
RAW Paste Data