Windows automate telnet

前端 未结 3 504
半阙折子戏
半阙折子戏 2021-02-07 05:33

I would like to run a set of commands that would typically be run in telnet(from c#).

For example I would like to run the following

using System;
using          


        
相关标签:
3条回答
  • 2021-02-07 06:16

    Based on comments I understand that you can use actual telnet protocol implementation instead of calling to telnet.exe, so

    Form1.cs

    using MinimalisticTelnet;
    using System;
    using System.Text.RegularExpressions;
    using System.Windows.Forms;
    
    namespace Telnet
    {
        public partial class Form1 : Form
        {
            public Form1()
            {
                InitializeComponent();
            }
    
            private MinimalisticTelnet.TelnetConnection _tc;
    
            private void Form1_Load(object sender, EventArgs e)
            {
                _tc = new TelnetConnection("telehack.com", 23);
            }
    
            private void timer1_Tick(object sender, EventArgs e)
            {
                ProcessOutput();
            }
    
            private void btnSendCommand_Click(object sender, EventArgs e)
            {
                if (_tc.IsConnected)
                {
                    _tc.WriteLine(tbCommand.Text.Trim());
                    tbCommand.Clear();
                    tbCommand.Focus();
                    ProcessOutput();
                }
            }
    
            private void ProcessOutput()
            {
                if (!_tc.IsConnected)
                    return;
    
                var s = _tc.Read();
                s = Regex.Replace(s, @"\x1b\[([0-9,A-Z]{1,2}(;[0-9]{1,2})?(;[0-9]{3})?)?[m|K]?", "");
                tbOutput.AppendText(s);
            }
        }
    }
    

    TelnetInterface.cs

    // minimalistic telnet implementation
    // conceived by Tom Janssens on 2007/06/06  for codeproject
    //
    // http://www.corebvba.be
    
    
    
    using System;
    using System.Collections.Generic;
    using System.Text;
    using System.Net.Sockets;
    
    namespace MinimalisticTelnet
    {
        enum Verbs
        {
            WILL = 251,
            WONT = 252,
            DO = 253,
            DONT = 254,
            IAC = 255
        }
    
        enum Options
        {
            SGA = 3
        }
    
        class TelnetConnection
        {
            TcpClient tcpSocket;
    
            int TimeOutMs = 100;
    
            public TelnetConnection(string Hostname, int Port)
            {
                tcpSocket = new TcpClient(Hostname, Port);
    
            }
    
            public string Login(string Username, string Password, int LoginTimeOutMs)
            {
                int oldTimeOutMs = TimeOutMs;
                TimeOutMs = LoginTimeOutMs;
                string s = Read();
                if (!s.TrimEnd().EndsWith(":"))
                    throw new Exception("Failed to connect : no login prompt");
                WriteLine(Username);
    
                s += Read();
                if (!s.TrimEnd().EndsWith(":"))
                    throw new Exception("Failed to connect : no password prompt");
                WriteLine(Password);
    
                s += Read();
                TimeOutMs = oldTimeOutMs;
                return s;
            }
    
            public void WriteLine(string cmd)
            {
                Write(cmd + Environment.NewLine);
            }
    
            public void Write(string cmd)
            {
                if (!tcpSocket.Connected) return;
                byte[] buf = System.Text.ASCIIEncoding.ASCII.GetBytes(cmd.Replace("\0xFF", "\0xFF\0xFF"));
                tcpSocket.GetStream().Write(buf, 0, buf.Length);
            }
    
            public string Read()
            {
                if (!tcpSocket.Connected) return null;
                StringBuilder sb = new StringBuilder();
                do
                {
                    ParseTelnet(sb);
                    System.Threading.Thread.Sleep(TimeOutMs);
                } while (tcpSocket.Available > 0);
                return sb.ToString();
            }
    
            public bool IsConnected
            {
                get { return tcpSocket.Connected; }
            }
    
            void ParseTelnet(StringBuilder sb)
            {
                while (tcpSocket.Available > 0)
                {
                    int input = tcpSocket.GetStream().ReadByte();
                    switch (input)
                    {
                        case -1:
                            break;
                        case (int)Verbs.IAC:
                            // interpret as command
                            int inputverb = tcpSocket.GetStream().ReadByte();
                            if (inputverb == -1) break;
                            switch (inputverb)
                            {
                                case (int)Verbs.IAC:
                                    //literal IAC = 255 escaped, so append char 255 to string
                                    sb.Append(inputverb);
                                    break;
                                case (int)Verbs.DO:
                                case (int)Verbs.DONT:
                                case (int)Verbs.WILL:
                                case (int)Verbs.WONT:
                                    // reply to all commands with "WONT", unless it is SGA (suppres go ahead)
                                    int inputoption = tcpSocket.GetStream().ReadByte();
                                    if (inputoption == -1) break;
                                    tcpSocket.GetStream().WriteByte((byte)Verbs.IAC);
                                    if (inputoption == (int)Options.SGA)
                                        tcpSocket.GetStream().WriteByte(inputverb == (int)Verbs.DO ? (byte)Verbs.WILL : (byte)Verbs.DO);
                                    else
                                        tcpSocket.GetStream().WriteByte(inputverb == (int)Verbs.DO ? (byte)Verbs.WONT : (byte)Verbs.DONT);
                                    tcpSocket.GetStream().WriteByte((byte)inputoption);
                                    break;
                                default:
                                    break;
                            }
                            break;
                        default:
                            sb.Append((char)input);
                            break;
                    }
                }
            }
        }
    }
    

    This is Windows Forms app with 2 textboxes and 1 button and a timer (interval is 1000ms). I've used code from CodeProject (linked in original question) with some changes to make it actually work.

    0 讨论(0)
  • 2021-02-07 06:16

    Coding this may be hard. However, there are free tools out there for Telnet scripting, see Expect for one. If you have an C# application then perhaps your code could generate the Expect script and then run Expect?

    0 讨论(0)
  • 2021-02-07 06:19

    Sending the information to telnet seems like it should be straightforward; use SendKeys(). The question becomes how to capture the output.

    I found this YouTube video that should help: https://www.youtube.com/watch?v=BDTCviA-5M8

    The solution in the video doesn't really address keeping the session open. I'm a bit outside my knowledge area here, but I believe you can start telnet in a worker thread, send commands to it with SendKeys(), capture the output as described in the video, then parse it.

    Does that sufficiently resolve the requirement?

    0 讨论(0)
提交回复
热议问题