With PuTTY, I connect to an SSH server and then I execute a command that constantly output logs (multiple lines per second). During this process I can send some keystrokes which are commands, ie. putting 123
or Esc which stops the process. If I put a valid keystroke I can see it on output device, so I always know if keystroke was sent or not.
我想以编程方式执行此操作 - 连接到 SSH 服务器,执行主命令,然后将一些击键作为命令发送给它,同时监视日志,在其中我可以看到对命令的响应。
所以我想用 SSH.NET 来做这件事——它是一个简洁的 SSH 工具,它输出可靠,而且使用起来很舒服。但是我有一个问题 - 我可以连接到该服务器,执行命令,但是当它转储日志时我无法向它发送任何击键。
我尝试过使用的方法CreateShellStream
:
shellStream.WriteLine('keystroke in ascii or just string')
-
sshClient.CreateCommand('keystroke in ascii or just string')
进而sshClient.Execute()
;
- using
StreamWriter(shellstream)
并写信给它
我尝试过 ascii 代码、UTF-16 代码、字符串,不幸的是没有任何效果。
使用 Plink(PuTTY 命令行工具)完成的相同操作工作得很好,但它更加混乱,我更喜欢使用 SSH.NET。您知道使用 SSH.NET 和 Plink 发送击键有什么区别吗?为什么它可以与 Plink 完美配合?我尝试过使用 Wireshark 来调试它,不幸的是 SSH 使得它很难做到这一点。
对于 Plink,我基本上使用这样的东西:
ProcessStartInfo psi = new ProcessStartInfo("plink.exe", arguments);
psi.RedirectStandardError = true;
psi.RedirectStandardOutput = true;
psi.RedirectStandardInput = true;
psi.UseShellExecute = false;
plink = Process.Start(psi);
StreamWriter input = plink.StandardInput;
StreamReader output = plink.StandardOutput;
input.WriteLine("startCommand"); //Starts the process responsible for logs
input.Write("950"); //It correctly sends the keystrokes
// Some code regarding reading logs from output, some other commands sent to ssh server...
Console.WriteLine("Exiting...");
input.Write('\u001b'); //ESC in UTF16
我认为 SSH.NET 在发送其他任何内容之前会等待最后一个命令结束,但我不知道如何更改它。
我尝试使用 SSH.NET:
using (var client = new SshClient(host, user, new PrivateKeyFile(key)))
{
int timoutCounter = 0;
do
{
timoutCounter++;
try { client.Connect(); }
catch (Exception e)
{
Console.WriteLine("Connection error: " + e.Message);
}
} while (!client.IsConnected);
ShellStream stream = client.CreateShellStream("shell", 200, 24, 1920, 1080, 4096);
// it starts the process on remote ssh server that
stream.WriteLine("startCommand");
Console.Write("Waiting for any key...");
Console.ReadKey();
for (int i = 0; i < 30; i++)
{
// Just some quick way for me to know that the device fully loaded
stream.Expect("LogKeyWord");
}
Console.WriteLine("Device started");
Console.ReadKey();
// Different ways of entering commands during log output that I've tried
stream.Write("5");
Console.Write("Waiting for any key...");
Console.ReadKey();
stream.WriteLine("6");
Console.Write("Waiting for any key...");
Console.ReadKey();
stream.Write("\u001b");
Console.Write("Waiting for any key...");
Console.ReadKey();
var test97 = new StreamWriter(stream);
test97.Write("7");
Console.Write("Waiting for any key...");
Console.ReadKey();
test97.WriteLine("8");
Console.Write("Waiting for any key...");
Console.ReadKey();
client.RunCommand("11");
Console.Write("Waiting for any key...");
Console.ReadKey();
var test = client.CreateCommand("31");
test.Execute();
Console.Write("Waiting for any key...");
Console.ReadKey();
client.Disconnect();
}