cmd.exe进程。保持会话交互并通过标准输出捕获

时间:2014-07-09 23:05:31

标签: c# windows

我一直在查看与我相似的帖子,但要么我的问题没有得到解答,要么我无法理解答案。我在这里使用了很多代码片段来开始;所以,谢谢你; - )

我的要求是创建一个交互式cmd.exe窗口,并将结果输出到文本框(以解析数据),例如,发送命令" cd /&#34 ;;看输出然后发送命令" dir"表明我在新目录中。一旦我破解了这个,那么我打算解析收到的文本输出并扩展我的应用程序

我现在可以做两件事,但不能同时做。

我是c#的新手,现在已经坚持了几天。代码发布如下。
proc1设法保持会话处于活动状态,而proc2将文本输出到文本框(我稍后将其输出到要解析的字符串中);但我无法同时做到这两个要求。

我可以解释更多为什么我要这样做,但最终创建一个概念应用程序,以便在基础知识破解后进行扩展......

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Diagnostics;
using System.IO;


namespace ConsoleTest_07_07_14
{
    public partial class Form1 : Form
    {
        Process proc1 = new Process();
        Process proc2 = new Process();

        public Form1()
        {
            InitializeComponent();
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            SetProc1();
            proc1.Start();
            SetProc2();
            proc2.Start();
        }

        public void SetProc1()
        {
            proc1.StartInfo.FileName = @"C:\Windows\System32\cmd.exe";
            proc1.StartInfo.WorkingDirectory = @"C:\Windows";
            proc1.StartInfo.UseShellExecute = false;
            proc1.StartInfo.WindowStyle = ProcessWindowStyle.Hidden;
            proc2.StartInfo.CreateNoWindow = true;
            proc1.StartInfo.RedirectStandardInput = true;
         // proc2.StartInfo.RedirectStandardOutput = true;
        }

        public void SetProc2()
        {
            proc2.StartInfo.FileName = @"C:\Windows\System32\cmd.exe";
            proc2.StartInfo.WorkingDirectory = @"C:\Windows";
            proc2.StartInfo.UseShellExecute = false;
            proc2.StartInfo.WindowStyle = ProcessWindowStyle.Hidden;
            proc2.StartInfo.CreateNoWindow = true;
            proc2.StartInfo.RedirectStandardInput = true;
            proc2.StartInfo.RedirectStandardOutput = true;
        }

        private void button1_Click(object sender, EventArgs e)
        {
            // process1
            StreamWriter SW1 = proc1.StandardInput;
            SW1.WriteLine(textBox3.Text);
        }

        private void button2_Click(object sender, EventArgs e)
        {
            proc2.StartInfo.Arguments = "/c dir";
            proc2.Start();
            StreamReader SR2 = proc2.StandardOutput;
            textBox2.Text = SR2.ReadToEnd();
        }
    }
}

2 个答案:

答案 0 :(得分:2)

如果您只想构建自己的cmd包装器,基本上将命令输入TextBox并将其输出到另一个TextBox,这样做:

public partial class Form1 : Form
{
    string OutputData;

    public Form1()
    {
        InitializeComponent();
    }

    public ProcessStartInfo SetProcStartInfo(string Command)
    {
        ProcessStartInfo procStartInfo = new ProcessStartInfo("cmd.exe", "/c " + Command);
        procStartInfo.WorkingDirectory = @"C:\Windows";
        procStartInfo.UseShellExecute = false;
        procStartInfo.CreateNoWindow = true;
        procStartInfo.RedirectStandardOutput = true;

        return procStartInfo;
    }

    private void button1_Click(object sender, EventArgs e)
    {
        ProcessStartInfo procStartInfo = SetProcStartInfo(this.textBox1.Text);

        using (Process proc1 = Process.Start(procStartInfo))
        {
            proc1.EnableRaisingEvents = true;
            proc1.OutputDataReceived += OnOutputDataReceived;
            proc1.BeginOutputReadLine();
        }
    }

    void OnOutputDataReceived(object sender, DataReceivedEventArgs e)
    {
        if (e.Data != null)
        {
            this.OutputData += e.Data + Environment.NewLine;
            SetText(this.OutputData);
        }
    }

    delegate void SetTextCallback(string text);

    private void SetText(string text)
    {
        if (this.textBox2.InvokeRequired)
        {
            SetTextCallback d = new SetTextCallback(SetText);
            this.Invoke(d, new object[] { text });
        }
        else
        {
            this.textBox2.Text = text;
        }
    }
}

答案 1 :(得分:1)

我设法实现了我想要的(下面的代码供参考)(感谢工作中的朋友;-)) 我的目标是保持Windows cmd会话处于活动状态,并将任何输出文本捕获到要解析的字符串。

例如,ssh到linux框,运行ifconfig,然后解析Linux框上可用的接口。 最终目标是给软件公司一个我希望他们扩展的例子。我希望Application能用c#编写,因为这是我希望SW house能够提升的应用程序的基础。

现在我已经掌握了基础知识,我会看看ssh篇....

感谢所有评论和回复

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Diagnostics;
using System.IO;


namespace ConsoleTest_07_07_14
{
    public partial class Form1 : Form
    {
        delegate void SetTextCallBack(string text);
        Process proc1 = new Process();
        string proc1_OutputText;

        public Form1()
        {
            InitializeComponent();
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            SetProc1();
        }

        public void SetProc1()
        {
            proc1.StartInfo.FileName = @"C:\Windows\System32\cmd.exe";
            proc1.StartInfo.WorkingDirectory = @"C:\Windows";
            proc1.StartInfo.UseShellExecute = false;
            proc1.StartInfo.CreateNoWindow = true;
            proc1.StartInfo.RedirectStandardInput = true;
            proc1.StartInfo.RedirectStandardError = true; //why was it false??
            proc1.StartInfo.RedirectStandardOutput = true;
            proc1.OutputDataReceived += new DataReceivedEventHandler(MyProc1OutputHandler);
            proc1.ErrorDataReceived += new DataReceivedEventHandler(MyProc1OutputHandler);
            proc1.Start();
            proc1.BeginOutputReadLine();
        }

        private void button1_Click(object sender, EventArgs e)
        {
            // send command to process1
            clearProc1_text();
            SendProcessCommand(proc1, textBox2.Text);
        }

        private void SendProcessCommand (Process proc, string text)
        {
            StreamWriter SW = proc.StandardInput;
            SW.WriteLine(text);
        }

        private void setProc1_OutputText(string text)
        {
            if (this.textBox1.InvokeRequired)
            {
                SetTextCallBack d = new SetTextCallBack(setProc1_OutputText);
                this.Invoke(d, new object[] { text });
            }
            else 
            {
                proc1_OutputText += text + Environment.NewLine;
                this.textBox1.Text = proc1_OutputText; 
            }
        }

        private void clearProc1_text ()
        {
            clearText1();
            clearProc1_OutputText();
        }

        private void clearText1() { textBox1.Text = ""; }
        private void clearProc1_OutputText() { proc1_OutputText = ""; }

        private static void MyProc1OutputHandler(object sendingProcess, DataReceivedEventArgs outline)
        {
            Debug.Print("Called");
            if (!String.IsNullOrEmpty(outline.Data))
            { //Debug.Print(outline.Data)
                Form1 f = (Form1)Form.ActiveForm;
                if (f != null)
                {
                    f.setProc1_OutputText(outline.Data);
                }
            }
        }

    }
}