我想从使用c#运行的Windows框中通过ssh运行命令

时间:2010-09-04 12:46:30

标签: c# windows unix ssh

请注意,这必须位于Windows框中,因为我使用c#访问有关Windows的信息

(我需要来自windows box和linux box的信息,而且我认为制作一个没有gui运行的程序/脚本并且在没有用户干预的情况下从linux盒子访问窗口会更加困难,如果不是这样的话请告诉我,我很乐意在* nix上运行,只有访问windows信息在Windows上运行的部分)。

有一个很好的c#api从windows获取这些信息,在* nix上它足够简单,可以运行命令并根据我的需要解析输出。

似乎没有太多关于在c#中使用ssh的建议,sharpSSH和Granados好像多年来都没有更新,它们是否合适?我是否可能担心安全问题?

(我正在检索的信息不敏感但是如果ssh实现可能有未修补的安全漏洞(如果它们多年没有更新)我担心有人窃取我的凭据。

还有其他不错的c#ssh库吗?如果命令输出很简单,我应该运行plink / putty(难道为plink运行一个windows cmd shell,并捕获输出(有没有办法在没有shell弹出的情况下执行它)?

P.S。虽然商业图书馆看起来不错,但我更喜欢免费的东西(如果可能的话,在成本和免费资源中)。

6 个答案:

答案 0 :(得分:6)

示例代码

C#有几个商业SSH客户端库。以下代码显示了如何连接到* nix框,运行命令并使用我们的Rebex SSH Shell读取响应。

// create client, connect and log in  
Ssh client = new Ssh();
client.Connect(hostname);
client.Login(username, password);

// run the 'uname' command to retrieve OS info 
string systemName = client.RunCommand("uname -a");
// display the output 
Console.WriteLine("OS info: {0}", systemName);

client.Disconnect();

对于高级方案(例如交互式命令),请参阅SSH Shell Tutorial

参考文献&稳定性

您可能已经在使用Rebex SSH核心库而不知道它。 Rebex SFTP(使用此SSH lib作为传输层)被Microsoft用于包括Expression Web和Visual Studio 2010在内的多个产品中.Robex SSH Shell是“正好”的另一层(最值得注意的是添加终端)仿真器)。

您可以从http://www.rebex.net/ssh-shell.net/download.aspx下载试用版。支持论坛使用与此站点非常相似的引擎,并在http://forum.rebex.net/

上运行

免责声明:我参与了Rebex SSH的开发

答案 1 :(得分:3)

在没有shell弹出的情况下调用plink非常容易。

不显示窗口的技巧是设置ProcessStartInfo.CreateNoWindow = true 添加一些错误处理,你就完成了。

--- PlinkWrapper.cs ---

using System.Collections.Generic;
using System.Diagnostics;

namespace Stackoverflow_Test
{
    public class PlinkWrapper
    {
        private string host { get; set; }
        /// <summary>
        /// Initializes the <see cref="PlinkWrapper"/>
        /// Assumes the key for the user is already loaded in PageAnt.
        /// </summary>
        /// <param name="host">The host, on format user@host</param>
        public PlinkWrapper(string host)
        {
            this.host = host;
        }

        /// <summary>
        /// Runs a command and returns the output lines in a List&lt;string&gt;.
        /// </summary>
        /// <param name="command">The command to execute</param>
        /// <returns></returns>
        public List<string> RunCommand(string command)
        {
            List<string> result = new List<string>();

            ProcessStartInfo startInfo = new ProcessStartInfo("plink.exe");
            startInfo.UseShellExecute = false;
            startInfo.RedirectStandardOutput = true;
            startInfo.CreateNoWindow = true;
            startInfo.Arguments = host + " " + command;
            using (Process p = new Process())
            {
                p.StartInfo = startInfo;
                p.Start();
                while (p.StandardOutput.Peek() >= 0)
                {
                    result.Add(p.StandardOutput.ReadLine());
                }
                p.WaitForExit();
            }

            return result;
        }
    }
}

--- END PlinkWrapper.cs ---

称之为

PlinkWrapper plink = new PlinkWrapper("albin@mazarin");
foreach (var str in plink.RunCommand("pwd"))
    Console.WriteLine("> " + str);

,输出就像

> /home/albin

plink的好处在于它经过充分验证并与pageant很好地集成。

答案 2 :(得分:2)

我使用SharpSsh lib在linux和windows box之间创建一个异步目录同步程序(我选择sftp进行安全文件传输)。多年来保持不变并不意味着它不安全。

它非常易于使用:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Tamir.SharpSsh;

namespace sftpex
{
    class Program
    {
        static void Main(string[] args)
        {
            try
            {
                SshExec exec = new SshExec(ipAddress, username, password);
                Console.Write("Connecting...");
                exec.Connect();
                Console.WriteLine("OK");
                if (exec.Connected)
                    Console.WriteLine(exec.Cipher);

                while (true)
                {
                    Console.Write("Enter a command to execute ['Enter' to cancel]: ");
                    string command = Console.ReadLine();
                    if (command == "") break;
                    string output = exec.RunCommand(command);
                    string[] m = output.Split('\n');
                    for(int i=0; i<m.Length; i++)
                        Console.WriteLine(m[i]);
                }
                Console.Write("Disconnecting...");
                exec.Close();
                Console.WriteLine("OK");
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message);
            }
        }
    }
}

答案 3 :(得分:1)

如果你不反对与C libs互操作,我相信OpenSSH是最适合这项工作的图书馆之一。

答案 4 :(得分:0)

我过去使用SharpSSH在Linux机器上执行命令。有很多错误,我不得不修改代码来修复其中的一些,但最终它有点工作......

答案 5 :(得分:0)

有一个商业软件IP * Works SSH可以完成这项工作。