Stian Tofte
Stian Tofte

Reputation: 213

Sending strings to a command prompt that's already running

I'm trying to make GUI for "bukkit".

But I ran into some issues.. But it was easy enough to read the output from the console. But actually sending strings back into it. was a bit harder.

Here is how I read the output and puts it into a textbox.

    private void button1_Click(object sender, EventArgs e)
    {
        backgroundWorker1.RunWorkerAsync();
        //ExecuteCommandSync("java -Xmx1024M -jar C:\\mc1\\craftbukkit.jar -o true");
    }

    private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
    {
        server("java -Xmx1024M -jar F:\\Skrivebord\\MCTestServer\\craftbukkit.jar -o true");
    }

    public void server(string command)
    {
        try
        {
            var procStartInfo =
                new System.Diagnostics.ProcessStartInfo("cmd", "/c " + command);


            procStartInfo.RedirectStandardOutput = true;
            procStartInfo.UseShellExecute = false;
            procStartInfo.CreateNoWindow = true;
            var proc = new System.Diagnostics.Process();
            proc.OutputDataReceived += proc_OutputDataReceived;
            //proc.StandardInput += proc_InputData;
            proc.StartInfo = procStartInfo;
            //processname = proc.ProcessName.ToString();
            proc.Start();
            proc.BeginOutputReadLine();
            proc.WaitForExit();
        }
        catch (Exception objException)
        {
            Console.WriteLine("Error: " + objException.Message);
            // Log the exception
        }
    }

    void proc_OutputDataReceived(object sender, System.Diagnostics.DataReceivedEventArgs e)
    {
        this.Invoke((MethodInvoker)delegate
        {
            string textForConsole = "";
            if (!(textBox1.Text == ""))
            {
                StringBuilder builder = new StringBuilder();
                builder.Append(e.Data);
                builder.AppendLine();
                textForConsole = builder.ToString();
                builder.Append(textBox1.Text).AppendLine();
                textBox1.Text = builder.ToString();
            }
            else
            {
                textBox1.Text = e.Data;
            }
        });
    }

This works perfectly. But I have no idea on how to actually sending strings back or into a console from my C# application..

I have tried this(Googled my way to this. But did not work.):

[DllImport("user32.dll", EntryPoint = "FindWindowEx")]
    public static extern IntPtr FindWindowEx(IntPtr hwndParent, IntPtr hwndChildAfter, string lpszClass, string lpszWindow);
    [DllImport("user32.dll")]
    static extern bool SetForegroundWindow(IntPtr hWnd);
    [DllImport("User32.dll")]
    public static extern int SendMessage(IntPtr hWnd, int uMsg, int wParam, string lParam);

private void button2_Click(object sender, EventArgs e)
    {
        Process p = Process.GetProcessesByName("java").FirstOrDefault();
        if (p != null)
        {
            IntPtr h = p.MainWindowHandle;
            SetForegroundWindow(h);
            SendKeys.SendWait(textBox2.Text);
        }           
    }

Anyone know how to do this?

Upvotes: 1

Views: 850

Answers (1)

Remus Rusanu
Remus Rusanu

Reputation: 294187

You're using RedirectStandardOutput to read the output. The next logical step would be to use RedirectStandardInput to write into the input. If your application is a proper pipe then it will work.

As about how to send keys to a program, there is a well known article: You can't simulate keyboard input with PostMessage which so happens also gives the correct answer: SendInput. Google for examples.

And no, you do not need to 'find' the process. You just started it, is right there:' proc.Start()!!

Upvotes: 1

Related Questions