編集の要約なし
編集の要約なし
36行目: 36行目:
<br>
<br>
SSH.NETには他にも様々な機能があり、ファイル転送、SFTPサポート、ポートフォワーディング等ができる。<br>
SSH.NETには他にも様々な機能があり、ファイル転送、SFTPサポート、ポートフォワーディング等ができる。<br>
<br>
==== SshClientクラスのインスタンス生成 ====
* 認証方法
<syntaxhighlight lang="c#">
using Renci.SshNet;
// パスワード認証の場合
var client = new SshClient("192.168.1.100", "<ユーザ名>", "<パスワード>");
// ポート番号を指定する場合 (デフォルトは22)
var client = new SshClient("192.168.1.100", 2222, "<ユーザ名>", "<パスワード>");
// 公開鍵認証を使用する場合
var keyFile = new PrivateKeyFile(@"/path/to/private_key");
var client = new SshClient("192.168.1.100", "<ユーザ名>", keyFile);
// 公開鍵認証を使用する場合 (パスフレーズ付き秘密鍵の場合)
var keyFile = new PrivateKeyFile(@"C:\path\to\private_key", "passphrase");
var client = new SshClient("192.168.1.100", "<ユーザ名>", keyFile);
</syntaxhighlight>
<br>
* 接続情報をまとめて管理する方法
<syntaxhighlight lang="c#">
using Renci.SshNet;
var connectionInfo = new ConnectionInfo(
    "192.168.1.100",
    "username",
    new PasswordAuthenticationMethod("<ユーザ名>", "<パスワード>")
);
var client = new SshClient(connectionInfo);
</syntaxhighlight>
<br>
* タイムアウト設定
<syntaxhighlight lang="c#">
csharpvar connectionInfo = new ConnectionInfo(
    "192.168.1.100",
    "username",
    new PasswordAuthenticationMethod("<ユーザ名>", "<パスワード>")
)
{
    Timeout = TimeSpan.FromSeconds(30)  // 接続タイムアウト
};
var client = new SshClient(connectionInfo);
</syntaxhighlight>
<br>
==== Connectメソッドによる接続確立 ====
* 接続方法
<syntaxhighlight lang="c#">
using Renci.SshNet;
var client = new SshClient("192.168.1.100", "username", "password");
try
{
    client.Connect();
    Console.WriteLine("接続成功");
    Console.WriteLine($"接続状態: {client.IsConnected}");
}
catch (SshException ex)
{
    Console.WriteLine($"SSH接続エラー: {ex.Message}");
}
catch (SocketException ex)
{
    Console.WriteLine($"ネットワークエラー: {ex.Message}");
}
finally
{
    if (client.IsConnected)
    {
      client.Disconnect();
    }
    client.Dispose();
}
</syntaxhighlight>
<br>
* 接続状態の確認
<syntaxhighlight lang="c#">
// 接続前
Console.WriteLine($"接続前: {client.IsConnected}"); // False
client.Connect();
// 接続後
Console.WriteLine($"接続後: {client.IsConnected}"); // True
Console.WriteLine($"サーバー情報: {client.ConnectionInfo.ServerVersion}");
</syntaxhighlight>
<br>
* 自動再接続の方法
<syntaxhighlight lang="c#">
public bool ConnectWithRetry(SshClient client, int maxRetries = 3, int delaySeconds = 5)
{
    for (int i = 0; i < maxRetries; i++)
    {
      try
      {
          client.Connect();
          Console.WriteLine("接続成功");
          return true;
      }
      catch (Exception ex)
      {
          Console.WriteLine($"接続失敗 ({i + 1}/{maxRetries}): {ex.Message}");
          if (i < maxRetries - 1)
          {
            Thread.Sleep(delaySeconds * 1000);
          }
      }
    }
    return false;
}
</syntaxhighlight>
<br>
==== RunCommandメソッドとResultプロパティ ====
* コマンドの実行
<syntaxhighlight lang="c#">
using Renci.SshNet;
using (var client = new SshClient("192.168.1.100", "username", "password"))
{
    client.Connect();
    // コマンド実行
    var cmd = client.RunCommand("ls -la /home");
    // 結果の取得
    Console.WriteLine("=== 標準出力 ===");
    Console.WriteLine(cmd.Result);
    // エラー出力の取得
    if (!string.IsNullOrEmpty(cmd.Error))
    {
      Console.WriteLine("=== エラー出力 ===");
      Console.WriteLine(cmd.Error);
    }
    // 終了コードの取得
    Console.WriteLine($"終了コード: {cmd.ExitStatus}");
}
</syntaxhighlight>
<br>
* 複数のコマンドの実行
<syntaxhighlight lang="c#">
// セミコロンで区切って複数コマンドを実行
var cmd = client.RunCommand("cd /tmp; pwd; ls -l");
Console.WriteLine(cmd.Result);
// &&を使用して前のコマンドが成功した場合のみ次を実行
var cmd2 = client.RunCommand("mkdir testdir && cd testdir && touch testfile.txt");
Console.WriteLine(cmd2.Result);
</syntaxhighlight>
<br>
* 長時間実行されるコマンド
<syntaxhighlight lang="c#">
// タイムアウトを設定
var cmd = client.RunCommand("sleep 10; echo 'Done'");
cmd.CommandTimeout = TimeSpan.FromSeconds(15);
Console.WriteLine(cmd.Result);
</syntaxhighlight>
<br>
* 標準出力と標準エラー出力を区別する
<syntaxhighlight lang="c#">
var cmd = client.RunCommand("ls /existing_dir /non_existing_dir");
// 標準出力 (正常な結果)
if (!string.IsNullOrEmpty(cmd.Result))
{
    Console.WriteLine("成功した出力:");
    Console.WriteLine(cmd.Result);
}
// 標準エラー(エラーメッセージ)
if (!string.IsNullOrEmpty(cmd.Error))
{
    Console.WriteLine("エラー出力:");
    Console.WriteLine(cmd.Error);
}
// 終了コードで判定
if (cmd.ExitStatus == 0)
{
    Console.WriteLine("コマンドは正常終了しました");
}
else
{
    Console.WriteLine($"コマンドは異常終了しました (コード: {cmd.ExitStatus})");
}
</syntaxhighlight>
<br>
==== Executeメソッドによる終了コード取得 ====
* CreateCommandとExecuteの使用方法
<syntaxhighlight lang="c#">
using Renci.SshNet;
using (var client = new SshClient("192.168.1.100", "<ユーザ名>", "<パスワード>"))
{
    client.Connect();
    // CreateCommandでコマンドオブジェクトを作成
    using (var cmd = client.CreateCommand("ls -l /home"))
    {
      // Executeメソッドで実行し、標準出力を取得
      string output = cmd.Execute();
      Console.WriteLine("=== コマンド出力 ===");
      Console.WriteLine(output);
      Console.WriteLine($"終了コード: {cmd.ExitStatus}");
      if (!string.IsNullOrEmpty(cmd.Error))
      {
          Console.WriteLine($"エラー: {cmd.Error}");
      }
    }
}
</syntaxhighlight>
<br>
* RunCommand および CreateCommand + Executeの違い
<syntaxhighlight lang="c#">
// 方法1 : RunCommand (簡単であるが詳細制御が少ない)
var result1 = client.RunCommand("ls -l");
Console.WriteLine(result1.Result);
// 方法2 : CreateCommand + Execute (詳細な制御が可能)
using (var cmd = client.CreateCommand("ls -l"))
{
    string output = cmd.Execute();
    Console.WriteLine(output);
    // より詳細な情報が取得可能
    Console.WriteLine($"実行時間: {cmd.CommandTimeout}");
}
</syntaxhighlight>
<br>
* 終了コードによる分岐処理
<syntaxhighlight lang="c#">
using (var cmd = client.CreateCommand("test -f /path/to/file.txt"))
{
    cmd.Execute();
    switch (cmd.ExitStatus)
    {
      case 0:
          Console.WriteLine("ファイルが存在します");
          break;
      case 1:
          Console.WriteLine("ファイルが存在しません");
          break;
      default:
          Console.WriteLine($"エラーが発生しました (コード: {cmd.ExitStatus})");
          break;
    }
}
</syntaxhighlight>
<br>
* 非同期実行とストリーム処理
<syntaxhighlight lang="c#">
using (var cmd = client.CreateCommand("find / -name '*.log' 2>/dev/null"))
{
    var asyncResult = cmd.BeginExecute();
    // 出力をリアルタイムで読み取る
    var outputStream = cmd.OutputStream;
    using (var reader = new StreamReader(outputStream))
    {
      string line;
      while ((line = reader.ReadLine()) != null)
      {
          Console.WriteLine($"見つかったファイル: {line}");
      }
    }
    cmd.EndExecute(asyncResult);
    Console.WriteLine($"検索完了(終了コード: {cmd.ExitStatus})");
}
</syntaxhighlight>
<br>
==== エラーハンドリング ====
<syntaxhighlight lang="c#">
public int ExecuteCommandSafely(SshClient client, string command)
{
    try
    {
      using (var cmd = client.CreateCommand(command))
      {
          string output = cmd.Execute();
          if (cmd.ExitStatus == 0)
          {
            Console.WriteLine("成功:");
            Console.WriteLine(output);
          }
          else
          {
            Console.WriteLine($"コマンド実行エラー (コード: {cmd.ExitStatus})");
            if (!string.IsNullOrEmpty(cmd.Error))
            {
                Console.WriteLine($"エラー詳細: {cmd.Error}");
            }
          }
          return cmd.ExitStatus;
      }
    }
    catch (SshException ex)
    {
      Console.WriteLine($"SSH例外: {ex.Message}");
      return -1;
    }
    catch (Exception ex)
    {
      Console.WriteLine($"予期しないエラー: {ex.Message}");
      return -1;
    }
}
</syntaxhighlight>
<br><br>
<br><br>