C#与CLI进程交互 - 标准输入不起作用

时间:2017-01-24 21:03:37

标签: c# asp.net .net command-line-interface cisco

我写了以下代码。由于某种原因,StreamWriter / RedirectStandardInput似乎不起作用。我正在尝试与之交互的CLI似乎不接受甚至不接收我输入的命令。

还有一些其他奇怪的事情,我也不明白。我必须使用While循环来读取StandardOuput的所有行。

process.StandardOutput.ReadToEnd();

什么都不返回。只有 ReadLine(); 才会被识别。

修改

我现在也注意到,如果我在任何process.StandardInput.WriteLine(“”)之后设置了断点。打电话,永远不会达到断点。该过程永远不会返回到我的C#代码。

这也发生在我的process.StandardOutput.ReadLine()循环之后。当它到达最后一行时,它永远不会返回到我的c#代码。

代码如下:

        Process process = new Process();
        process.StartInfo.FileName = @"C:\Program Files (x86)\Cisco\Cisco AnyConnect Secure Mobility Client\vpncli.exe";
        process.StartInfo.RedirectStandardInput = true;
        process.StartInfo.RedirectStandardOutput = true;
        process.StartInfo.RedirectStandardError = true;
        process.StartInfo.UseShellExecute = false;
        process.StartInfo.CreateNoWindow = true;
        process.Start();


        process.StandardInput.AutoFlush = true;
        string line = string.Empty;
        while ((line = process.StandardOutput.ReadLine()) != null)
        {
            Console.WriteLine("CLI Says: " + line);
        }

        process.StandardInput.WriteLine("connect vpn.service.domain.com");

        line = string.Empty;
        while ((line = process.StandardOutput.ReadLine()) != null)
        {
            Console.WriteLine("CLI Says: " + line);
        }

        process.StandardInput.WriteLine("0");

        line = string.Empty;
        while ((line = process.StandardOutput.ReadLine()) != null)
        {
            Console.WriteLine("CLI Says: " + line);
        }

        process.StandardInput.WriteLine("MyUsername");

        line = string.Empty;
        while ((line = process.StandardOutput.ReadLine()) != null)
        {
            Console.WriteLine("CLI Says: " + line);
        }

        process.StandardInput.WriteLine("MyPassword");

        line = string.Empty;
        while ((line = process.StandardOutput.ReadLine()) != null)
        {
            Console.WriteLine("CLI Says: " + line);
        }

我在调试控制台中收到的输出是:

CLI Says: Cisco AnyConnect Secure Mobility Client (version 3.1.10010) .
CLI Says: 
CLI Says: 
CLI Says: Copyright (c) 2004 - 2015 Cisco Systems, Inc.  All Rights Reserved.
CLI Says: 
CLI Says: 
CLI Says: 
CLI Says: 
CLI Says:   >> state: Disconnected
CLI Says: 
CLI Says: 
CLI Says: VPN> 
CLI Says:   >> state: Disconnected
CLI Says: 
CLI Says: 
CLI Says: VPN> 
CLI Says:   >> notice: Ready to connect.
CLI Says: 
CLI Says: 
CLI Says: VPN> 
CLI Says:   >> registered with local VPN subsystem.
CLI Says: 
CLI Says: 
CLI Says: VPN> 

2 个答案:

答案 0 :(得分:0)

ReadToEnd()不会返回,直到遇到流的末尾。换句话说,在ReadToEnd()返回后,流处于一种状态,以便不再有数据出现(你已经到达终点)。

因此,您可能并不想使用ReadToEnd()。根据您处理输出的方式,您可能希望使用ReadLine(),或只使用Read()

答案 1 :(得分:0)

您的循环将继续,直到流结束:

    string line = string.Empty;
    while ((line = process.StandardOutput.ReadLine()) != null)
    {
        Console.WriteLine("CLI Says: " + line);
    }

这将读取整行逐行打印出来的整个流,只有在流实际结束后才会停止。 ReadLine()函数将读取流的每个字符,直到它返回回车符,然后将它读取的所有字符作为字符串返回。它只会在流结束时返回null。

你需要做的是处理每一行并弄清楚你想用它做什么,也就是把逻辑放在读取循环中,如:

    enum State {
        Initial,
        Connecting,
        ..
    }

    string line = string.Empty;
    State state = State.Initial;
    while ((line = process.StandardOutput.ReadLine()) != null)
    {
        Console.WriteLine("CLI Says: " + line);
        if(line == string.Empty) continue; // skip blank lines
        if(line.StartsWith("VPN>")
        {
            switch(state) 
            { 
               case State.Initial: 
                   SendConnect(); 
                   state = State.Connecting;
                   break;
               ..
            }
        }
        else // check what is being printed by vpn is correct, no errors, etc.
    }

然后,您可以扩展switch语句,随时移动状态并发送不同的输入等。