Fes*_*lly 2 c# ssh automation putty plink
我试图通过plink.exe连接到unix终端.目标是让我可以将文本读回字符串.
我的困境是,我工作的银行使用的是旧的as400类型系统,我们通常通过腻子访问.我正在尝试开发一个自动化套件,它将与系统连接并运行作业并分析输出等.
所以我想我会通过C#使用plink.如果我通过命令提示符运行代码,我会得到(大致)我需要的文本.但是我在我的C#代码中遇到了一个问题,因为它只是挂起而且我从来没有得到过响应.
我想要的是这样的:
连接到服务器输入命令回读屏幕//更多命令等
到目前为止,这是我的代码:
class Program
{
static void Main(string[] args)
{
ProcessStartInfo psi = new ProcessStartInfo(@"C:\Windows\System32\cmd");
psi.RedirectStandardInput = true;
psi.RedirectStandardOutput = true;
psi.WindowStyle = System.Diagnostics.ProcessWindowStyle.Normal;
psi.UseShellExecute = false;
psi.CreateNoWindow = false;
Process process = Process.Start(psi);
string cmdForTunnel = @"c:\putty\plink -ssh jonkers@bankhq -pw automationhero";
process.StandardInput.WriteLine(cmdForTunnel);
// process.WaitForExit();
Thread.Sleep(30000);
string output = process.StandardOutput.ReadToEnd();
Console.WriteLine(output);
//DoBusinessLogic();
process.StandardInput.WriteLine("logout");
Thread.Sleep(10000);
if (process.HasExited)
{
process.Close();
process.Dispose();
}
}
}
Run Code Online (Sandbox Code Playgroud)
我不确定问题在哪里,因为正如我所说的通过命令行使用plink测试,但我的解决方案上面只是挂起.我已经尝试在stackoverflow上使用其他人的解决方案,但它们似乎都没有为我工作,因为我不断得到这个挂起.非常感谢提示.
编辑
我现在决定使用Renci Sharp SSH库并围绕这个构建我自己的框架.它效果更好.
MrP*_*lch 10
所以我只想测试plink
自己,结果很愉快.
正如我在评论中说,您不能使用ReadToEnd
之前您发送的退出,除非你想命令,阻止你的当前主题.
实际上你可以在使用之前发送一堆命令(包括exit
或者logout
)ReadToEnd
,但是我确实建议执行Read asynchrounusly,因为它更强大.
现在有几种方法可以对流进行异步读取.
本Process
类实际上提供Events
的是是在输入数据上调.您可以为这些创建处理程序Events
.这些事件是:
OutputDataReceived
ErrorDataReceived
他们的事件处理程序提供包含数据的字符串.
您可以使用stdout/stdin BeginRead
的StreamReader
实例.
但是在这里我提供了一个代码示例,它使用简单的多线程以更粗糙的方式完成它:
public string RequestInfo(string remoteHost, string userName, string password, string[] lstCommands) {
m_szFeedback = "Feedback from: " + remoteHost + "\r\n";
ProcessStartInfo psi = new ProcessStartInfo()
{
FileName = PLINK_PATH, // A const or a readonly string that points to the plink executable
Arguments = String.Format("-ssh {0}@{1} -pw {2}", userName, remoteHost, password),
RedirectStandardError = true,
RedirectStandardOutput = true,
RedirectStandardInput = true,
UseShellExecute = false,
CreateNoWindow = true
};
Process p = Process.Start(psi);
m_objLock = new Object();
m_blnDoRead = true;
AsyncReadFeedback(p.StandardOutput); // start the async read of stdout
AsyncReadFeedback(p.StandardError); // start the async read of stderr
StreamWriter strw = p.StandardInput;
foreach (string cmd in lstCommands)
{
strw.WriteLine(cmd); // send commands
}
strw.WriteLine("exit"); // send exit command at the end
p.WaitForExit(); // block thread until remote operations are done
return m_szFeedback;
}
private String m_szFeedback; // hold feedback data
private Object m_objLock; // lock object
private Boolean m_blnDoRead; // boolean value keeping up the read (may be used to interrupt the reading process)
public void AsyncReadFeedback(StreamReader strr)
{
Thread trdr = new Thread(new ParameterizedThreadStart(__ctReadFeedback));
trdr.Start(strr);
}
private void __ctReadFeedback(Object objStreamReader)
{
StreamReader strr = (StreamReader)objStreamReader;
string line;
while (!strr.EndOfStream && m_blnDoRead)
{
line = strr.ReadLine();
// lock the feedback buffer (since we don't want some messy stdout/err mix string in the end)
lock (m_objLock) { m_szFeedback += line + "\r\n"; }
}
}
Run Code Online (Sandbox Code Playgroud)
因此,如果要获取远程主机调用的用户目录的内容:
String feedback = RequestInfo("remote.ssh.host.de", "user", "password", new string[] { "ls -la" });
Run Code Online (Sandbox Code Playgroud)
显然,您可以替换自己的地址,凭据和命令列表.
您也可能想要清理输出字符串.在我的情况下,我发送给远程主机的命令会回显到输出中,从而出现在返回字符串中.