web-dev-qa-db-ja.com

C#のSSHサーバーでコマンドを実行する方法

C#コードを使用してこのアクションを実行する必要があります。

  1. バックグラウンドでPuTTY.exeを開きます(これはcmdウィンドウのようなものです)
  2. iPアドレスを使用してリモートホストにログインする
  3. ユーザー名とパスワードを入力してください
  4. 複数のコマンドを順番に実行します。
  5. 別のコマンドを実行して、その前に実行したコマンドが正常に実行されたことを伝える応答を受け取ります

だから私はこのようにしようとしています:

ProcessStartInfo proc = new ProcessStartInfo() 
{
     FileName = @"C:\PuTTY.exe",
     UseShellExecute = true, //I think I need to use Shell execute ?
     RedirectStandardInput = false,
     RedirectStandardOutput = false,
     Arguments = string.Format("-ssh {0}@{1} 22 -pw {2}", userName, hostIP, password)
     ... //How do I send commands to be executed here ?
};
Process.Start(proc);
11
Liran Friedman

https://sshnet.codeplex.com/ を試すことができます。これにより、PuTTYやウィンドウはまったく必要ありません。あなたも応答を得ることができます。それはsthに見えるでしょう。このような。

SshClient sshclient = new SshClient("172.0.0.1", userName, password);    
sshclient.Connect();
SshCommand sc= sshclient .CreateCommand("Your Commands here");
sc.Execute();
string answer = sc.Result;

編集:別のアプローチは、シェルストリームを使用することです。

次のようにShellStreamを作成します。

ShellStream stream = sshclient.CreateShellStream("customCommand", 80, 24, 800, 600, 1024);

次に、次のようなコマンドを使用できます。

  public StringBuilder sendCommand(string customCMD)
    {
        StringBuilder answer;

        var reader = new StreamReader(stream);
        var writer = new StreamWriter(stream);
        writer.AutoFlush = true; 
        WriteStream(customCMD, writer, stream);
        answer = ReadStream(reader);
        return answer;
    }

private void WriteStream(string cmd, StreamWriter writer, ShellStream stream)
    {
        writer.WriteLine(cmd);
        while (stream.Length == 0)
        {
            Thread.Sleep(500);
        }
    }

private StringBuilder ReadStream(StreamReader reader)
    {
        StringBuilder result = new StringBuilder();

        string line;
        while ((line = reader.ReadLine()) != null)
        {
            result.AppendLine(line);
        }
        return result;
    }
17
LzyPanda

@LzyPandaによる回答は機能しますが、SSH "Shell"チャネル(SshClient.CreateShellStream)を使用して、対話型端末のみを許可することは、コマンド実行の自動化には適していません。コマンドプロンプト、ANSIシーケンス、一部のコマンドのインタラクティブな動作など、多くの副作用があります。

自動化するには、SSH「exec」チャネルを使用します( SshClient.CreateCommand ):

using (var command = ssh.CreateCommand("command"))
{
    Console.Write(command.Execute());
}

複数のコマンドを実行する必要がある場合は、上記のコードを繰り返します。 1つのSSH接続に対して任意の数の「exec」チャネルを作成できます。

コマンドが互いに依存している場合(最初のコマンドが環境を変更した場合、たとえば、後者のコマンドで使用される変数)、1つのチャネル内で実行します。 &&;などのシェル構文を使用します。

using (var command = ssh.CreateCommand("command1 && command2"))
{
    Console.Write(command.Execute());
}

コマンド出力を継続的に読み取る必要がある場合は、以下を使用します。

using (var command = ssh.CreateCommand("command"))
{
    var asyncExecute = command.BeginExecute();
    command.OutputStream.CopyTo(Console.OpenStandardOutput());
    command.EndExecute(asyncExecute);
}

Stdoutとstderrの両方を含むExtendedOutputStreamを使用することもできます。 SSH.NETリアルタイムコマンド出力監視 を参照してください。


残念ながら、SSH.NETの「exec」チャネルの実装では、コマンドへの入力を提供できません。その使用例では、この制限が解決されるまで「シェル」チャネルに頼る必要があります。

5
Martin Prikryl