一个C#写的调用外部进程类

C# 调用外部进程的类,网上可以搜出很多来,为什么要再写一遍,实在是因为最近从网上拷贝了一个简单的例程用到项目中,运行有问题,后来研究了半天,才解决了这些问题。于是打算写这么一篇博文,一来说说调用一个外部进程这么简单的一件事究竟会有哪些问题,二来也希望我写的这个相对比较完整的类可以为软件开发的同道们节约一些脑细胞,以便集中优势兵力解决那些真正高深复杂的软件问题。

在开始正题之前,我们先来看一看网上比较常见的执行外部进程的函数

private string RunCmd(string command)
    {
      //例Process
      Process p = new Process();
      p.StartInfo.FileName = "cmd.exe";      //确定程序名
      p.StartInfo.Arguments = "/c " + command;  //确定程式命令行
      p.StartInfo.UseShellExecute = false;    //Shell的使用
      p.StartInfo.RedirectStandardInput = true;  //重定向输入
      p.StartInfo.RedirectStandardOutput = true; //重定向输出
      p.StartInfo.RedirectStandardError = true;  //重定向输出错误
      p.StartInfo.CreateNoWindow = true;     //设置置不显示示窗口
      p.Start();  //00
      //p.StandardInput.WriteLine(command);    //也可以用这种方式输入入要行的命令
      //p.StandardInput.WriteLine("exit");    //要得加上Exit要不然下一行程式
      return p.StandardOutput.ReadToEnd();    //输出出流取得命令行结果果
    }

这个方法应该是比较常见的调用外部进程的方法,我以前也一直是这样调用外部进程的,也没有碰到过什么问题。但这次调用的外部进程比较特殊,用这种方法调用就出现了两个问题。

第一个问题是这个被调用的外部进程有时候会出现异常,出现异常后Windows会弹出错误报告框,程序于是吊死在那里,必须手工干预。这个问题比较好解决,程序中设置一下注册表搞定。

第二个问题是调用这个外部进程(是一个控制台进程)后,程序会阻塞在p.StandardOutput.ReadToEnd();这一句,永远无法出来,被调用的那个控制台程序也被吊死。但该控制台进程在CMD 中是可以正常执行的。后来看来一些资料才发现原来原因是出在该控制台程序控制台输出大量字符串,管道重定向后,调用程序没有及时将管道中的输出数据取出,结果导致管道被阻塞,程序吊死。在这里还有另外一个问题,虽然这次没有遇到,但网上有其他人遇到,就是错误信息管道不及时取出数据,也会被阻塞,而且如果要同时取出两个管道的数据,必须要利用一个辅助线程才能实现。

时间: 2024-09-08 16:15:13

一个C#写的调用外部进程类的相关文章

【转】一个C#写的调用外部进程类

      2008-05-21 07:00作者:肖波出处:天极网责任编辑:nancy C# 调用外部进程的类,网上可以搜出很多来,为什么要再写一遍,实在是因为最近从网上拷贝了一个简单的例程用到项目中,运行有问题,后来研究了半天,才解决了这些问题.于是打算重写,一来说说调用一个外部进程这么简单的一件事究竟会有哪些问题,二来也希望我写的这个相对比较完整的类可以为软件开发的同道们节约一些脑细胞,以便集中优势兵力解决那些真正高深复杂的软件问题. 在开始正题之前,我们先来看一看网上比较常见的执行外部进程

急求:如何将vs的一个已经写好的mfc含有界面的主程序封装成mfcdll,供其他程序调用?

问题描述 急求:如何将vs的一个已经写好的mfc含有界面的主程序封装成mfcdll,供其他程序调用? 两个项目同时进行,一个是3d,一个是2d,现在需要把两个合在一起,需要把3d的mfc项目封装成dll供2d的mfc调用. 解决方案 一个完整的程序封装成dll是一个复杂的事情,尤其是你的程序使用了mfc框架,并且有大量的全局变量.你的团队要有足够的资源去做这件事情,它不亚于从头开发. 如果你们没有足够的资源,最好还是采用进程通讯和进程调用的方法,避免源代码的大改. 解决方案二: 直接利用VS的工

c++构造函数的初始化列表中初始化了一个类类型的成员,调用的是类类型的复制构造函数吧?

问题描述 c++构造函数的初始化列表中初始化了一个类类型的成员,调用的是类类型的复制构造函数吧? 如题:c++构造函数的初始化列表中初始化了一个类类型的成员,调用的是类类型的复制构造函数吧? 解决方案 什么?复制构造函数? 解决方案二: C++类构造函数列表初始化C++类构造函数初始化列表c++中什么类型的成员变量只能在构造函数的初始化列表中进行 解决方案三: 真是初始化列表,跟复制构造函数没关系,调用复制构造函数要看你是如何初始化的 解决方案四: 参数列表初始化成员是调用成员的构造函数,但是什

c++-我想创建可以在任何一个OnClick事件中调用的函数,怎么写?

问题描述 我想创建可以在任何一个OnClick事件中调用的函数,怎么写? 现在有一个单文档MFC程序,我想创建一个全局的函数或者类,可以在任何一个OnClick事件中调用,请问应该怎么写? 我是这样做的,定义了一个类A,然后A中的函数比如void b()是public的,在其他onclick事件中创建一个A的对象a,a.b();编译没问题,可是一连接就报错,为什么?我应该怎么写? 解决方案 如果单纯的想将OnClick中的功能分离成一个函数的话,你可以在OnClick这个函数所在的类比如说,CE

调用java进程时为什么找不到java类

问题描述 调用java进程时为什么找不到java类 您好,请问我在调用java进程时为什么找不到java类? 我用的是myeclipse,执行命令 Process p = run.exec("java cn.com.jit.ida.demo.ratk.InvokeProcess"); 时,发现没有调用InvokeProcess.java类 解决方案 你这没有编译,直接执行的,找不到.class文件.应该先使用javac命令 解决方案二: 你的路径对吗,是否在同一个目录下.

如何写一个主函数去调用这个函数,求指导

问题描述 如何写一个主函数去调用这个函数,求指导 bool imageSubtract(IplImage* src IplImage* dst){ int row = 0;//行 int col = 0;//列 uchar* pSrcData = NULL; uchar* pDstData = NULL; int stepSrc = 0; int stepDst = 0; if (!src || !dst){ return 0;}if ((src->height != dst->height)

如何写一个主函数去调用这个,求指导

问题描述 如何写一个主函数去调用这个,求指导 bool imageSubtract(IplImage* src IplImage* dst){ int row = 0;//行 int col = 0;//列 uchar* pSrcData = NULL; uchar* pDstData = NULL; int stepSrc = 0; int stepDst = 0; if (!src || !dst){ return 0;}if ((src->height != dst->height) &

C#如何调用一个DELPHI写的dll

问题描述 兄弟们我有个问题请教一下:我用C#调用一个DELPHI写的dll,dll中有integer,pchar,single数据类型,integer和single类型都能读出来就是读pchar类型有问题,这个函数是个读卡函数,调用会报这个错"对PInvoke函数"WindowsApplication1!WindowsApplication1.mz_读医保卡::Freadcard"的调用导致堆栈不对称.原因可能是托管的PInvoke签名与非托管的目标签名不匹配.请检查PInv

Node.js中创建和管理外部进程详解_node.js

Node被设计用来高效的处理I/O操作,但是你应该知道,有些类型的程序并不适合这种模式.比如,如果你打算用Node处理一个CPU密集的任务,你可能会堵塞事件循环,并因此降低了程序的响应.替代办法是,把CPU密集的任务分配给一个单独的进程来处理,从而释放事件循环.Node允许你产生进程,并把这个新进程做为它父进程的子进程.在Node里,子进程可以和父进程进行双向通信,而且在某种程度上,父进程还可以监控和管理子进程. 另外一种需要使用子进程的情况是,当你想简单地执行一个外部命令,并让Node获取命令