【问题标题】:Execute multiple command lines with the same process using C#使用 C# 执行具有相同进程的多个命令行
【发布时间】:2011-02-20 12:55:58
【问题描述】:

嗨,根据我的最后一个问题here 我尝试编写一个 sql 编辑器或类似的东西,这样我尝试从 C# 连接到 CMD 并执行我的命令。 现在我的问题是在我无法获得 SQLPLUS 命令之后连接到 SQLPLUS,并且我查看的其他资源不满足我。请帮助我在连接到 sqlplus 后如何运行我的进程来运行我的 sql 命令?现在我使用这个代码:

//Create process
System.Diagnostics.Process pProcess = new System.Diagnostics.Process();

//strCommand is path and file name of command to run
pProcess.StartInfo.FileName = strCommand;

//strCommandParameters are parameters to pass to program
pProcess.StartInfo.Arguments = strCommandParameters;

pProcess.StartInfo.UseShellExecute = false;

//Set output of program to be written to process output stream
pProcess.StartInfo.RedirectStandardOutput = true;

//Optional
pProcess.StartInfo.WorkingDirectory = strWorkingDirectory;

//Start the process
pProcess.Start();

//Get program output
string strOutput = pProcess.StandardOutput.ReadToEnd();

//Wait for process to finish
pProcess.WaitForExit();

我定制了它。我分离了初始化,我创建了一次进程对象,但仍然有问题,运行第二个命令我使用这些代码进行第二次调用:

pProcess.StartInfo.FileName = strCommand;

//strCommandParameters are parameters to pass to program
pProcess.StartInfo.Arguments = strCommandParameters;
//Start the process
pProcess.Start();

//Get program output
string strOutput = pProcess.StandardOutput.ReadToEnd();

//Wait for process to finish
pProcess.WaitForExit();

提前致谢

【问题讨论】:

  • FWIW,那些 cmets 只是噪音......
  • 你的意思是你想启动一次进程,但是向它发送多个命令?如果是这样,为什么不每次都发送多个命令从头开始整个过程​​(双关语不是故意的,但无论如何都很有趣)
  • 正是...我只运行一次 sqlplus 之后我给用户/密码,如果它登录发送 Sql.PL 命令。我有点困惑:(实际上每次我尝试连接数据库并运行我的命令时都需要时间……但我不知道,也许其他软件也像这样使用?哈?有什么想法吗?

标签: c# command


【解决方案1】:

您的问题有点令人困惑,但我想我看到了您的问题。首先,您应该查看这篇博文以查看 common issues with System.Diagnostics.Process。您的代码碰巧违反了此处未列出的代码。 Process 对象本身的重用。

你需要像这样重构代码:

    class MyProcessStarter
    {
        private ProcessStartInfo _startInfo = new ProcessStartInfo();
        public MyProcessStarter(string exe, string workingDir)
        {
            _startInfo.WorkingDirectory = workingDir;
            _startInfo.FileName = exe;
            _startInfo.UseShellExecute = false;
            _startInfo.RedirectStandardOutput = true;
        }

        public string Run(string arguments)
        {
            _startInfo.Arguments = arguments;
            Process p = Process.Start(_startInfo);
            p.Start();
            string strOutput = p.StandardOutput.ReadToEnd();
            p.WaitForExit();
            return strOutput;
        }
    }

我编写了一个更完整、更准确的实现,称为ProcessRunner。下面演示了执行相同操作的用法:

using CSharpTest.Net.Processes;
partial class Program
{
    static int Main(string[] args)
    {

        ProcessRunner run = new ProcessRunner("svn.exe");
        run.OutputReceived += new ProcessOutputEventHandler(run_OutputReceived);
        return run.Run("update", "C:\\MyProject");
    }

    static void run_OutputReceived(object sender, ProcessOutputEventArgs args)
    {
        Console.WriteLine("{0}: {1}", args.Error ? "Error" : "Output", args.Data);
    }
}

【讨论】:

  • 谢谢老兄,第一个代码很有用,但我仍然有错误!!!你知道吗,我的进程是这样​​运行的:我把它翻译成 exec 命令:sqlplus user/pass@db sqlplus prompt "amir";
【解决方案2】:

您需要从输入读取所有数据,然后再发送另一个命令!

如果没有可用的数据,你不能要求 READ ......有点糟糕不是吗?

我的解决方案...当要求阅读时...要求阅读大缓冲区...比如 1 MEGA...

您需要等待至少 100 毫秒...示例代码...

Public Class Form1

    Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
        Dim oProcess As New Process()
        Dim oStartInfo As New ProcessStartInfo("cmd.exe", "")
        oStartInfo.UseShellExecute = False
        oStartInfo.RedirectStandardOutput = True
        oStartInfo.RedirectStandardInput = True
        oStartInfo.CreateNoWindow = True
        oProcess.StartInfo = oStartInfo
        oProcess.Start()

        oProcess.StandardInput.WriteLine("dir")


        Threading.Thread.Sleep(100)

        Dim Response As String = String.Empty

        Dim BuffSize As Integer = 1024 * 1024
        Dim bytesRead As Integer = 0

        Do

            Dim x As Char() = New Char(BuffSize - 1) {}
            bytesRead = oProcess.StandardOutput.Read(x, 0, BuffSize)

            Response = String.Concat(Response, String.Join("", x).Substring(0, bytesRead))            

        Loop While oProcess.StandardOutput.Peek >= 0



        MsgBox(Response)
        Response = String.Empty



        oProcess.StandardInput.WriteLine("dir c:\")




        Threading.Thread.Sleep(100)


        bytesRead = 0

        Do

            Dim x As Char() = New Char(BuffSize - 1) {}
            bytesRead = oProcess.StandardOutput.Read(x, 0, BuffSize)

            Response = String.Concat(Response, String.Join("", x).Substring(0, bytesRead))
            'Response = String.Concat(Response, String.Join("", x))

        Loop While oProcess.StandardOutput.Peek >= 0

        MsgBox(Response)


    End Sub
End Class

【讨论】:

    猜你喜欢
    • 2010-10-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-11-10
    • 1970-01-01
    • 1970-01-01
    • 2015-06-16
    相关资源
    最近更新 更多