zoukankan      html  css  js  c++  java
  • .Net执行cmd命令

    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变量为批处理文件全路径:

    C小Tip:Process.WaitForExit()与死锁  - fengqiaa - 风之筑的博客C小Tip:Process.WaitForExit()与死锁  - fengqiaa - 风之筑的博客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 InstallScriptsCreate01.sql (

    echo bas

    sqlplus %1/%2@%3 @InstallScriptsCreate01.sql | %HideSQLPlusRows%

    REM > LogsCreate_%1.txt

    )

    if exist InstallScriptsCreate02.sql (

    ......

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

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

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

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

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

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

    echo Tables on level 0:

    if exist InstallScriptsCreate01.sql (

    echo bas

    sqlplus %1/%2@%3 @InstallScriptsCreate01.sql | %HideSQLPlusRows% > LogsCreate_%1.txt

    )

    ......

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

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

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

  • 相关阅读:
    数据排序
    (一)Spark简介Java&Python版Spark
    醒 了
    祈福
    可以接受失败,但不选择放弃
    烦中偷乐
    Yahoo! UI Library入门
    文章内容的简单优化方法
    Asp.Net网站速度优化
    ASP.NET实现GZIP压缩优化
  • 原文地址:https://www.cnblogs.com/lxshanye/p/3805462.html
Copyright © 2011-2022 走看看