0

I have been trying to figure this for hours, and can't seem to find a straight answer. I have found similar questions but none seem to work with what I am trying to do here. I am trying to avoid having to write to a file. If I can redirect to a variable, that would be great.

Given the following code:

        static void Main(string[] args) {

        const int VK_RETURN = 0x0D;
        const int WM_KEYDOWN = 0x100;

        var cmd = new Process();

        cmd.StartInfo.FileName = "cmd.exe";
        cmd.StartInfo.UseShellExecute = false;
        cmd.StartInfo.RedirectStandardInput = true;
        cmd.StartInfo.RedirectStandardOutput = true;
        cmd.Start();

        using (var stdin = cmd.StandardInput) {
            stdin.WriteLine("ftp");
            stdin.WriteLine("open localhost");
            stdin.WriteLine("anonymous");
            var hWnd = System.Diagnostics.Process.GetCurrentProcess().MainWindowHandle;
            PostMessage(hWnd, WM_KEYDOWN, VK_RETURN, 0);
            stdin.WriteLine("ls");
            stdin.WriteLine("close localhost");
            stdin.WriteLine("bye");

        }
        cmd.WaitForExit();
        cmd.Close();
    }

How do I redirect the ls output to a variable?

4
  • Process.start: how to get the output? Commented Nov 12, 2015 at 15:26
  • Console.SetOut() method ? Commented Nov 12, 2015 at 15:38
  • Why are you running ftp.exe via cmd.exe? You are adding unnecessary complexity and another possible point of failure. Run it directly. Commented Nov 13, 2015 at 9:02
  • Yes. That's what I ended up doing. After I was done with the code it hit me. Commented Nov 13, 2015 at 16:36

1 Answer 1

1

I was able to grab output from the console by handling the OutputDataReceived event. https://msdn.microsoft.com/en-us/library/system.diagnostics.process.outputdatareceived(v=vs.110).aspx

using System;
using System.Diagnostics;
using Microsoft.VisualStudio.TestTools.UnitTesting;

namespace UnitTestProject1
{
    [TestClass]
    public class UnitTest1
    {
        [TestMethod]
        public void TestMethod1()
        {
            const int VK_RETURN = 0x0D;
            const int WM_KEYDOWN = 0x100;

            var cmd = new Process();

            cmd.StartInfo.FileName = "cmd.exe";
            cmd.StartInfo.UseShellExecute = false;
            cmd.StartInfo.RedirectStandardInput = true;
            cmd.StartInfo.RedirectStandardOutput = true;

            // Capture output
            cmd.OutputDataReceived += (sender, args) =>
            {
                if (string.IsNullOrEmpty(args.Data) == false)
                {
                    var x = args.Data;
                }
            };

            cmd.Start();
            // Need to call this method in order to raise the OutputDataReceivedEvent for each line of output
            cmd.BeginOutputReadLine();


            using (var stdin = cmd.StandardInput)
            {
                stdin.WriteLine("ftp");
                stdin.WriteLine("open localhost");
                stdin.WriteLine("anonymous");
                var hWnd = Process.GetCurrentProcess().MainWindowHandle;
                PostMessage(hWnd, WM_KEYDOWN, VK_RETURN, 0);
                stdin.WriteLine("ls");
                stdin.WriteLine("close localhost");
                stdin.WriteLine("bye");
            }
            cmd.WaitForExit();
            cmd.Close();
        }

        private void PostMessage(IntPtr hWnd, int wmKeydown, int vkReturn, int i)
        {
            // No idea what you are doing here
        }
    }
}
Sign up to request clarification or add additional context in comments.

1 Comment

This works. I need to filter out first few lines and the last, but atleast I get the content. Thank you.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.