知识大全 如何获取子进程的输出
Posted 标准
篇首语:厌伴老儒烹瓠叶,强随举子踏槐花。本文由小常识网(cha138.com)小编为大家整理,主要介绍了知识大全 如何获取子进程的输出相关的知识,希望对你有一定的参考价值。
经常看到论坛中有人问到当用Process组件启动新的进程后 如何获取它的输出的问题 采取将子进程的输出定向到一个临时文件中 当然也可以解决问题 但是这样每次父进程从临时文件中获取信息后 还要删除该临时文件 毕竟比较麻烦 其实 Process提供了几个属性可以获取输出 框架sdk的帮助文档里面就有这方面的例子 但是对于如何同时获取错误输出和标准输出方面没有给出具体代码 本文将给出实例并对管道的特性作一些说明
一 获取子进程标准输出和错误输出的的方法
我们写一个小程序p cs 用它来产生标准输出和错误输出 //p cs代码如下 using System;class class public static void Main() int i = ; string s = String Format( out: i); System Console Out WriteLine(s ); string s = String Format( err: ************************************************** i); System Console Error WriteLine(s ); 编译成p exe
获取子进程的标准输出和错误输出的源程序//p cs Process p = new Process( p exe );p StartInfo UseShellExecute = false; //指定不使用系统的外壳程序 而是直接启动被调用程序本身p StartInfo RedirectStandardOutput = true; //只有将此属性设为true 才能通过管道获取子进程输出p StartInfo RedirectStandardError = true;
p Start(); //启动子进程string output = p StandardOutput ReadToEnd(); //读取标准输出string error = p StandardError ReadToEnd(); //读取错误输出p WaitForExit(); //等待子进程执行完毕 上例中 父进程启动子进程后 就等待着从管道中取走标准输出 取走全部标准输出后取走错误输出 我们运行起来没有任何错误 但是一旦我门增加p exe中的标准输出和错误输出的字节数 for(i= ;i< ;i++) System Console Out WriteLine(s );for(i= ;i< ;i++) System Console Error WriteLine(s );编译后 再运行 就会发现父进程和子进程出现了死锁 只有强行关闭才能终止进程
二 管道 Process 组件通过管道与子进程进行通讯 如果同时重定向标准输出和标准错误 然后试图读取它们 当管道被填满时候就会出现问题 上例中 父进程只有读完了所有的标准输出才能读错误输出 而子进程的标准输出每当把管道填满时候 父进程都会取走 子进程接着向管道输出后续的标准输出 这都运行的很好 可是当子进程执行到输出错误输出的时候 由于子进程还没有运行结束 它的标准输出流就不会处于结束状态(虽然在我们的例子中它的 次循环的标准输出已经执行完毕) 这就导致父进程中的ReadToEnd()方法不会执行完毕 所以父进程中的p StandardError ReadToEnd()无法执行 从而管道中的错误输出无法被读取 子进程的后续错误输出无法写入管道 最终子进程和父进程彼此无限等待 出现了阻塞情况
子进程通过检查管道中最后一个字节是否被取走 来决定是否输出后续内容 也就是说 如果管道缓冲区中最后一个字节之前的所有内容都被取走 子进程仍然会处于等待中 如果前面所有字节都没有取走 但最后一个字节内容被取走 子进程会继续向管道里输出后续内容 当然这样只能输出一字节到管道中最后位置
我们如果把p cs中的string output = p StandardOutput ReadToEnd()改为 for(int i= ;i< * ;i++) Console Write((char) p StandardOutput Read());
就不会出现死锁情况 因为当获取标准输出的循环执行完后 会接着执行获取错误输出的语句 而不需等待标准输出流的结束 但是这种方法毫无实际意义 因为实际中 我们并不可能像本例中知道标准输出会有多少字节
三 用多线程分别获取标准输出和错误输出
对于这种情况框架文档中建议这样解决 创建两个线程 以便应用程序可以在单独的线程上读取每个流的输出 下面给出例子:
cha138/Article/program/net/201311/11610相关参考
用C#+WMI获取w3wp进程对应的程序池 以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧! 
驯服Tiger之访问环境变量和调用子进程 以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧! 访问平台
下列关于第二次工业革命对中国历史进程影响的叙述,正确的是__①使帝国主义侵略中国由商品输出为主转为资本输出为主
下列关于第二次工业革命对中国历史进程影响的叙述,正确的是_____①使帝国主义侵略中国由商品输出为主转为资本输出为主给人改变未来的力量②使帝国主义掀起了瓜分中国的狂潮③使中国完全沦为半殖民地半封建社会
输入输出的存储进程 请看以下存储进程 /*SP*/ CREATEPROCEDUREDBODELUSERALL AS SETNOCOUNTON BEGIN DELETEFROMDBO[
C#中启动进程的三种方法 以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!启动子进程不等待子进程结束
假脱机SPOOLING系统主要包括()A、脱机输入进程B、作业调度进程C、作业进程和脱机输出进程D、用户进程参考答案:ABC
假脱机SPOOLING系统主要包括()A、脱机输入进程B、作业调度进程C、作业进程和脱机输出进程D、用户进程参考答案:ABC
大部分人在写Shell过滤进程的时候都会使用grep在psaux的输出结果中查找指定的进程但此时也会把grep进程也显示出来比如查找pptpd进程会匹配出来两条 复制代码代码如下: [root@s
天气终于晴了但问题来了在实现两个站点间用户数据同步当使用php函数file_get_contents抓取执行远程页面时如果连接超时将会输出一个FatalError或相当的慢结果导致下面的代码不能运
以上是一个多数熟悉单线程编程的人在第一反应下给出的实现方法但是该类在运行的时候输出的结果却不是期望的HelloWorld!而是Hello这是由于线程的竞争条件导致的