Windows自动化telnet

我想运行一组通常在telnet中运行的命令(来自c#)。

例如,我想运行以下内容

using System; using System.Diagnostics; namespace InteractWithConsoleApp { class Program { static void Main(string[] args) { ProcessStartInfo cmdStartInfo = new ProcessStartInfo(); cmdStartInfo.FileName = @"C:\Windows\System32\cmd.exe"; cmdStartInfo.RedirectStandardOutput = true; cmdStartInfo.RedirectStandardError = true; cmdStartInfo.RedirectStandardInput = true; cmdStartInfo.UseShellExecute = false; cmdStartInfo.CreateNoWindow = true; Process cmdProcess = new Process(); cmdProcess.StartInfo = cmdStartInfo; cmdProcess.ErrorDataReceived += cmd_Error; cmdProcess.OutputDataReceived += cmd_DataReceived; cmdProcess.EnableRaisingEvents = true; cmdProcess.Start(); cmdProcess.BeginOutputReadLine(); cmdProcess.BeginErrorReadLine(); cmdProcess.StandardInput.WriteLine("telnet telehack.com"); int milliseconds = 2000; System.Threading.Thread.Sleep(milliseconds); cmdProcess.StandardInput.WriteLine("exit"); cmdProcess.StandardInput.WriteLine("exit"); cmdProcess.WaitForExit(); } static void cmd_DataReceived(object sender, DataReceivedEventArgs e) { Console.WriteLine(e.Data); } static void cmd_Error(object sender, DataReceivedEventArgs e) { Console.WriteLine(e.Data); } } } 

并保持telnet打开以运行后续命令。 例如,对于上面的问题,我想运行并接收以下输出,但我没有收到任何telnet输出。 它没有收到任何输出。 这是相关的。

 telnet telehack.com > Connected to TELEHACK port 53 It is 2:33 pm on Tuesday, September 1, 2015 in Mountain View, California, USA. There are 31 local users. There are 24906 hosts on the network. May the command line live forever. Command, one of the following: ? ac advent basic cal calc ching clear clock cowsay date echo eliza factor figlet finger fnord geoip help hosts ipaddr joke login md5 morse newuser notes octopus phoon pig ping primes privacy rain rand rfc rig roll rot13 sleep starwars traceroute units uptime usenet users uumap uupath uuplot weather when zc zork zrun .calc calc>2+2 > 4 

根据评论我明白你可以使用实际的telnet协议实现,而不是调用telnet.exe,所以

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,AZ]{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; } } } } } 

这是Windows Forms应用程序,包含2个文本框和1个按钮以及一个计时器(间隔为1000毫秒)。 我使用了CodeProject中的代码(在原始问题中链接)和一些更改,以使其实际工作。

编码这可能很难。 但是,有一些免费的工具用于Telnet脚本,请参阅Expect for one。 如果您有一个C#应用程序,那么您的代码可能会生成Expect脚本然后运行Expect?

将信息发送telnet似乎应该是直截了当的; 使用SendKeys() 。 问题变成了如何捕获输出。

我发现这个YouTubevideo应该有所帮助: https : //www.youtube.com/watch?v = BDTCviA-5M8

video中的解决方案并未真正解决保持会话开放的问题。 我有点在我的知识领域之外,但我相信你可以在工作线程中启动telnet ,使用SendKeys()向它发送命令,按照video中的描述捕获输出,然后解析它。

这是否足以解决要求?