如何在C#中输入通过CMD进程运行的应用程序?

时间:2014-01-08 09:49:20

标签: c# git cmd

我正在尝试这样做:

        Process p = new Process();
        ProcessStartInfo info = new ProcessStartInfo();
        info.FileName = "cmd.exe";
        info.RedirectStandardInput = true;
        info.UseShellExecute = false;

        p.StartInfo = info;
        p.Start();

        using (StreamWriter sw = p.StandardInput)
        {
            if (sw.BaseStream.CanWrite)
            {
                sw.WriteLine("git config --global user.name \"My Name\"");
                sw.WriteLine("git config --global user.email \"my email\"");
                sw.WriteLine("call start-ssh-agent");
                sw.WriteLine("ssh-add c:\\temp\\ServerPull.ppk");
                System.Threading.Thread.Sleep(10000);
                sw.WriteLine(Environment.NewLine);
                sw.WriteLine("git clone git@github.com:myrepo");
            }
        }

        Console.WriteLine("Done");
    }

问题是“ssh-add”命令想要输入密码,我不能让C#输入密码。在Thread.Sleep进入缓冲区之后的任何其他命令,直到我自己在CMD盒上输入一些东西。

Console.Writeline()输出到同一个框中,但实际上并没有“输入”

编辑为了清楚起见,我不打算做一个Console.ReadLine()或实际上从用户那里获得输入。命令是我需要它们的方式,但是我需要自动将字符串发送到另一个要求密码短语的应用程序(ssh-add)。通过sw.WriteLine编写密码短语不起作用,因为控制台在等待输入时不会执行任何代码。

修改 在编写我的第一个编辑时,我对评论中的一些代码建议有了一个特别的时刻。现在结束了这个:

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

    static void Main(string[] args)
    {
        Process p = new Process();
        ProcessStartInfo info = new ProcessStartInfo();
        info.FileName = "cmd.exe";
        info.RedirectStandardInput = true;
        info.UseShellExecute = false;

        p.StartInfo = info;
        p.Start();

        using (StreamWriter sw = p.StandardInput)
        {
            if (sw.BaseStream.CanWrite)
            {
                sw.WriteLine("git config --global user.name \"my name\"");
                sw.WriteLine("git config --global user.email \"my email\"");
                sw.WriteLine("call start-ssh-agent");

                var enterThread = new Thread(
                    new ThreadStart(
                        () =>
                        {
                            Thread.Sleep(10000);
                            var hWnd = System.Diagnostics.Process.GetCurrentProcess().MainWindowHandle;
                            PostMessage(hWnd, WM_KEYDOWN, VK_RETURN, 0);
                        }
                        ));

                enterThread.Start();
                sw.WriteLine("ssh-add c:\\temp\\ServerPull.ppk");
                sw.WriteLine("git clone myrepo");
                sw.WriteLine("ping 127.0.0.1");
            }
        }

        Console.WriteLine("Done");
    }

    [DllImport("User32.Dll", EntryPoint = "PostMessageA")]
    private static extern bool PostMessage(IntPtr hWnd, uint msg, int wParam, int lParam);

在延迟后发送回车键。我应该可以从那里修改它以发送我需要的任何东西。

3 个答案:

答案 0 :(得分:1)

这对于键入命令提示符非常有用

        foreach (var v in message)
        {
            PostMessage(cmdProcess.MainWindowHandle, WM_CHAR, (IntPtr)v, IntPtr.Zero);
        }

        PostMessage(cmdProcess.MainWindowHandle, WmKeyUp, (IntPtr)Keys.Enter, IntPtr.Zero);

答案 1 :(得分:0)

我认为你可以做到这一点,..

https://stackoverflow.com/a/9634490/3156689

此链接说明如何将返回键发送到控制台..这比模拟按键或关闭stdin流更好

答案 2 :(得分:0)

我认为您可以使用主要方法的args[]。请参阅下面的示例。

public class CommandLine

{

public static void Main(string[] args)

{

Process p = new Process();
    ProcessStartInfo info = new ProcessStartInfo();
    info.FileName = "cmd.exe";
    info.RedirectStandardInput = true;
    info.UseShellExecute = false;

    p.StartInfo = info;
    p.Start();

    using (StreamWriter sw = p.StandardInput)
    {
        if (sw.BaseStream.CanWrite)
        {
            sw.WriteLine(string.Format("git config --global user.name {0}",args[0]));
            sw.WriteLine(string.Format("git config --global user.email {0}",args[1]));
            sw.WriteLine("call start-ssh-agent");
            sw.WriteLine(string.Format("ssh-add {0}",args[2]));  
            System.Threading.Thread.Sleep(10000);
            sw.WriteLine(Environment.NewLine);
            sw.WriteLine("git clone git@github.com:myrepo");
        }
    }

    Console.WriteLine("Done");
}}

执行exe和命令行使用参数:

x:\> yourapp.exe user2645643 xyx@yourdomain.com c:\temp\ServerPull.ppk

更新

然后很简单。使用var inp = Console.ReadLine()并将输入变量放在任何位置。