using System;
using System.Collections;
using System.Configuration;
using System.Data;
using System.Linq;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.HtmlControls;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Xml.Linq;
using System.Diagnostics;

namespace WebForm
{
    public partial class _Default : System.Web.UI.Page
    {
        protected void Page_Load(object sender, EventArgs e)
        {
            Response.Write(ExeCommand("ping www.126.com"));
        }

public string ExeCommand(string commandText)
        {
            Process p = new Process();
            p.StartInfo.FileName = "cmd.exe";
            p.StartInfo.UseShellExecute = false;
            p.StartInfo.RedirectStandardInput = true;
            p.StartInfo.RedirectStandardOutput = true;
            p.StartInfo.RedirectStandardError = true;
            p.StartInfo.CreateNoWindow = true;
            string strOutput = null;
            try
            {
                p.Start();
                p.StandardInput.WriteLine(commandText);
                p.StandardInput.WriteLine("exit");
                strOutput = p.StandardOutput.ReadToEnd();
                p.WaitForExit();
                p.Close();
            }
            catch (Exception e)
            {
                strOutput = e.Message;
            }
            return strOutput;
        }
    }
}

WaitForExit

程序里我使用Process类启动命令行,执行批处理文件 'Create.cmd'(当我手工将此文件拖入命令行执行时,一切正常)。C#程序代码类似如下,其中batchFilePath变量为批处理文件全路径:

Code

m_BasicDataProc = new Process();

m_BasicDataProc.StartInfo.FileName = "cmd.exe";

m_BasicDataProc.StartInfo.CreateNoWindow = false;

m_BasicDataProc.StartInfo.UseShellExecute = false;

m_BasicDataProc.StartInfo.RedirectStandardOutput = true;

m_BasicDataProc.StartInfo.RedirectStandardInput = true;

m_BasicDataProc.StartInfo.WorkingDirectory = Path.GetDirectoryName(batchFilePath);

m_BasicDataProc.Start();

string batchFileName = Path.GetFileName(batchFilePath);

StreamWriter inputStream = m_BasicDataProc.StandardInput;

inputStream.WriteLine(batchFileName);

inputStream.Close();

m_BasicDataProc.WaitForExit();

m_BasicDataProc.EnableRaisingEvents = true;

批处理文件'Create.cmd'调用'sqlplus'来执行若干个sql文件:

//===================================================

echo Tables on level 0:

if exist InstallScripts\Create01.sql (

echo bas

sqlplus %1/%2@%3 @InstallScripts\Create01.sql | %HideSQLPlusRows%

REM > Logs\Create_%1.txt

)

if exist InstallScripts\Create02.sql (

......

//===================================================

出现的问题是程序运行到'm_BasicDataProc.WaitForExit();'这一行时就阴塞不动.

搞 了两天,最后发现原因是出现了死锁。由于标准输出流被重定向,而Process.StandardOutput的缓冲大小是有限制的(据说是4k),所以 当缓冲满了的时候(执行上面的批处理文件有很多的输出),子进程(cmd.exe)会等待主进程(C# App)读取并释放此缓冲,而主进程由于调用了WaitForExit()方法,则会一进等待子进程退出,最后形成死锁。

了解了原因后,有3种方法可以解决问题:

1)修改批处理文件,在调用sqlplus时将输出指定到一个log文件,这样被生定向到StandardOutput中的内容相对就少,不容易造成问题:

//===================================================

echo Tables on level 0:

if exist InstallScripts\Create01.sql (

echo bas

sqlplus %1/%2@%3 @InstallScripts\Create01.sql | %HideSQLPlusRows% > Logs\Create_%1.txt

)

......

//===================================================

2)修改C#代码,将'm_BasicDataProc.StartInfo.RedirectStandardOutput = false;',这样所有的输出会在命令行屏幕上直接输出,不会重定向到标准输出流中。

3) 修改C#代码,在'm_BasicDataProc.WaitForExit();'前添加 'm_BasicDataProc.BeginOutputReadLine();' 或 'm_BasicDataProc.StandardOutput.ReadToEnd();',通过读取输出流,以便释放相应的缓冲。

.Net执行cmd命令的更多相关文章

  1. JAVA之执行cmd命令

    感言在前:时隔好久没有更新博客园了,忙东忙西也没忙出个什么之所以然来.回首过去一两个月,只能用“疲倦”两个字来形容,而且是身心疲惫.每天11.12个小时的工作我都没觉得烦,但是总是想克服却又很难克服的 ...

  2. [转]Delphi执行CMD命令

    今天看到有人在问用代码执行CMD命令的问题,就总结一下用法,也算做个备忘. Delphi中,执行命令或者运行一个程序有2个函数,一个是winexec,一个是shellexecute.这两个大家应该都见 ...

  3. C# 执行CMD 命令

    /// <summary> /// 执行CMD 命令 /// </summary> /// <param name="strCommand">命 ...

  4. C# 执行CMD命令的方法

    /// <summary> /// 执行CMD命令 /// </summary> /// <param name="str"></para ...

  5. 如何使用Java执行cmd命令

    用JAVA代码实现执行CMD命令的方法! Runtime rt = Runtime.getRuntime(); Process p = rt.exec(String[] cmdarray);     ...

  6. java执行cmd命令并获取输出结果

    1.java执行cmd命令并获取输出结果 import java.io.BufferedReader; import java.io.InputStreamReader; import org.apa ...

  7. Java 调用并执行cmd命令

    cmd java 调用 执行 概要: Java 调用并执行cmd命令 Java | 复制 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 2 ...

  8. Atitit.执行cmd 命令行 php

    Atitit.执行cmd 命令行 php 1. 执行cmd 命令行,调用系统命令的基础 1 1.1. 实际执行模式 1 1.2. 空格的问题 1 1.3. 中文路径的问题,程序文件读取编码设置 1 1 ...

  9. node执行cmd命令方法

    var cmd='tasklist';//获取 子进程模块的exec方法,用于执行cmd命令var exec = require('child_process').exec; //运行 定义的cmd命 ...

  10. java中执行cmd命令

    一.java执行cmd命令的三种方式:http://www.jb51.net/article/80829.htm 参考:https://www.cnblogs.com/zhufu9426/p/7928 ...

随机推荐

  1. C#如何调用R

    1. 现在R中安装rscproxy库 > install.packages(rscproxy) > library(rscproxy)   2. 到这个网站http://rcom.univ ...

  2. Linux0.11从开机到准备执行main函数的启动学习

    最近一直在看操作系统以及内核设计的东西,不确定自己有能力会参与到类似的开发之中,但是争取能自己改造这内核玩一下,然后按照Linux From Scratch那样的把改造后的系统编译运行就心满意足了.正 ...

  3. windows已阻止此软件因为无法验证发行者怎么办

    出现提示windows已阻止此软件因为无法验证发行者怎么解决?有的时候访问某些网站会出现类似的提示.导致不能正常运行某个插件,遇到这个问题一般是浏览器的安全级别设置太高了,没有允许脚本控件运行   设 ...

  4. Java编程的逻辑 (41) - 剖析HashSet

    本系列文章经补充和完善,已修订整理成书<Java编程的逻辑>,由机械工业出版社华章分社出版,于2018年1月上市热销,读者好评如潮!各大网店和书店有售,欢迎购买,京东自营链接:http:/ ...

  5. java生成word的完美解决方案

    http://www.360doc.com/content/13/0731/10/13247663_303740756.shtml —————————————————————————————————— ...

  6. 给data设置数据

    console.log(JSON.stringify(that.data.navigator[0].content) + "--____+" + JSON.stringify(th ...

  7. E/MediaPlayer: start called in state 4, mPlayer(0xcc719a40)解决

    在使用MediaPlayer播放音频时报出 E/MediaPlayer: start called in state 4, mPlayer(0xcc719a40)错误 贴出代码 mMediaPlaye ...

  8. apk签名打包时报master password is required to unlock the password database.错误,或者signtrue versions无法勾选,以及Error:Execution failed for task ':app:lintVitalRelease'.

    1.如果在签名时android studio报"Master password is required to unlock the password database.The passwor ...

  9. 自然语言交流系统 phxnet团队 创新实训 个人博客 (十三)

    关于java socket的一些总结: Java Socket通信有很多的时候需要我们不断的学习.方面效率虽然不及C与C++但它以灵活语言优势,为大家广为使用. 本文就对在使用java做通信方面程序时 ...

  10. 数据表记录包含表索引和数值,请对表索引相同的记录进行合并,即将相同索引的数值进行求和运算,输出按照key值升序进行输出。

    题目描述 数据表记录包含表索引和数值,请对表索引相同的记录进行合并,即将相同索引的数值进行求和运算,输出按照key值升序进行输出. 输入描述: 先输入键值对的个数然后输入成对的index和value值 ...