亲爱的同学们,你们知道怎么在一个Win32 Console Application中同时打印中日韩新马泰非洲列国文字么?
反正我是不会╮(╯-╰)╭ 但是用GUI Application来做是很容易的。本来想移植putty中的终端模拟器,但是纯C啊,实力有限233
我们要求不高,只要能打印东西就行了。至于输入啊,信号啊什么的,再说嘛~
完整代码可在https://github.com/fffonion/MAClient/blob/gui/frmNiceTerm.cs 获得
首先,用Process类启动一个进程:
1 2 3 4 5 6 7 8 9 10 11 |
process = new Process(); process.StartInfo.FileName = "ping"; process.StartInfo.Arguments = "127.0.0.1"; process.StartInfo.UseShellExecute = false; process.StartInfo.RedirectStandardOutput = true;//重定向stdout process.StartInfo.RedirectStandardInput = true;//重定向stdin process.StartInfo.RedirectStandardError = true;//重定向stderr process.StartInfo.EnvironmentVariables["NICE_TERM"] = "1";//export环境变量 process.StartInfo.StandardOutputEncoding = Encoding.UTF8;//设置输出流编码 process.StartInfo.CreateNoWindow = true;//不显示窗口 process.Start(); |
之所以加一个环境变量,是因为这样我们就可以在程序中判断是否使用了这个NiceTerm
我们在界面里拖进一个richTextBox,然后
1 2 3 4 5 6 |
while(true) { String line=null; while ((line =process.StartInfo.StandardOutput.ReadLine()) != null) richTextBox1.AppendText(line+"\n"); richTextBox1.ScrollToCaret(); }; |
然后我们运行一下,发现跑得很好,基本和cmd里是一个效果。
但是这样做是有问题的。首先我们在主线程里使用了一个死循环,这习惯不好;再者,其实process.StartInfo.StandardOutput是一个StreamReader,读取是同步的而且有超时,也就是说,一定时间内没有stdout出来,它就是hang在那里不动了。
我们可以尝试将process.StartInfo.FileName = “python.exe”;让它运行一个每隔2秒print一次的脚本,你会发现卧槽整个程序都无响应了233
参考这个项目Embedding a Console in a C# Application – CodeProject之后,用backgroundWorker解决了这个问题。由于用this.outputWorker.RunWorkerAsync(); 包装了读取stdout的过程,因此读取工作就是异步的了,也就不会hang住了。
附上运行效果图:
接下去要研究下怎么发送Ctrl+C给process,以及处理stdin