for Push.

This commit is contained in:
nobobo
2026-06-01 13:23:34 +09:00
parent 9e093ea99f
commit a6550e9928
93 changed files with 10393 additions and 0 deletions
+302
View File
@@ -0,0 +1,302 @@
using KssSmaPlaLib.Commons;
using KssSmaPlaLib.Encryption;
using KssSmaPlaLib.IO.File;
using Renci.SshNet;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace KssSmaPlaLib.Communications
{
public class SftpUxer
{
public const string INIDIC_KEY_HOST = "Host";
public const string INIDIC_KEY_PORT = "Port";
public const string INIDIC_KEY_USERNAME = "UserName";
public const string INIDIC_KEY_PRIVATE_KEY_FILE_PATH = "PrivateKeyFilePath";
public const string INIDIC_KEY_PASS_PHRASE = "PassPhrase";
private readonly string _host;
private readonly int _port;
private readonly string _username;
private readonly string _privateKeyPath; // PuTTY形式でもOK
private readonly string _passPhrase;
public static bool TryCreateByDic(Dictionary<string, string> iniDic, out SftpUxer sftp, out string resultMessage)
{
sftp = null;
resultMessage = string.Empty;
// ホスト名
var host = DictionaryUxer.GetValueOrDefault(iniDic, INIDIC_KEY_HOST, string.Empty);
if (string.IsNullOrEmpty(host))
{
resultMessage = $"SFTPのホスト名が指定されていません。[キー:{INIDIC_KEY_HOST}]";
return false;
}
// ポート番号
var strPort = DictionaryUxer.GetValueOrDefault(iniDic, INIDIC_KEY_PORT, string.Empty);
if (int.TryParse(strPort, out var portNo) == false)
{
LoggerUxer.Error($"SFTPのポート番号が未指定または数値でありません。[キー:{INIDIC_KEY_PORT},ポート番号:{strPort}]");
return false;
}
// ユーザ名
var username = DictionaryUxer.GetValueOrDefault(iniDic, INIDIC_KEY_USERNAME, string.Empty);
if (string.IsNullOrEmpty(username))
{
LoggerUxer.Error($"SFTPのユーザ名が指定されていません。[キー:{INIDIC_KEY_USERNAME}]");
return false;
}
// プライベートキーファイルパス
var privateKeyPath = DictionaryUxer.GetValueOrDefault(iniDic, INIDIC_KEY_PRIVATE_KEY_FILE_PATH, string.Empty);
if (string.IsNullOrEmpty(privateKeyPath))
{
LoggerUxer.Error($"SFTPのプライベートキーファイルパスが指定されていません。[キー:{INIDIC_KEY_PRIVATE_KEY_FILE_PATH}]");
return false;
}
if (!File.Exists(privateKeyPath))
{
LoggerUxer.Error($"SFTPのプライベートキーファイルパスが存在しません。[キー:{INIDIC_KEY_PRIVATE_KEY_FILE_PATH},パス:{privateKeyPath}]");
return false;
}
// パスフレーズ
var passPhrase = DictionaryUxer.GetValueOrDefault(iniDic, INIDIC_KEY_PASS_PHRASE, string.Empty);
// ↓パスフレーズなしの場合もあり(必須としない)
//if (string.IsNullOrEmpty(passPhrase))
//{
// LoggerUxer.Error($"SFTPのパスフレーズが指定されていません。[キー:{INIDIC_KEY_PASS_PHRASE}]");
// return false;
//}
var passPhraseDec = string.Empty;
if (!string.IsNullOrEmpty(passPhrase))
{
// パスフレーズの復号化
if (!SimpleEncryptUxer.Decrypt(passPhrase, out passPhraseDec, out string messageForMe))
{
LoggerUxer.Error($"SFTPのパスフレーズ復号化で失敗しました。[キー:{INIDIC_KEY_PASS_PHRASE},エラー内容:{messageForMe}]");
return false;
}
}
// オブジェクト生成
sftp = new SftpUxer(host, portNo, username, privateKeyPath, passPhraseDec);
return true;
}
private SftpUxer(string host, int port, string username, string privateKeyPath, string passPhrase)
{
_host = host;
_port = port;
_username = username;
_privateKeyPath = privateKeyPath;
_passPhrase = passPhrase;
}
public bool TestConnect(out string resultMessage)
{
resultMessage = string.Empty;
try
{
PrivateKeyFile keyFile;
if(!string.IsNullOrEmpty(_passPhrase))
{
// パスフレーズあり
keyFile = new PrivateKeyFile(_privateKeyPath, _passPhrase);
}
else
{
// パスフレーズなし
keyFile = new PrivateKeyFile(_privateKeyPath);
}
var keyFiles = new[] { keyFile };
using (var client = new SftpClient(_host, _port, _username, keyFiles))
{
client.Connect();
client.Disconnect();
}
return true;
}
catch (Exception ex)
{
resultMessage = $"SFTPのテスト接続に失敗しました。[ホスト:{_host},ポート:{_port},ユーザ名:{_username},プライベートキーファイルパス:{_privateKeyPath},エラー内容:{ex.Message}]";
return false;
}
}
public bool Upload(List<string> filePathList, string remotePath, out string resultMessage)
{
resultMessage = string.Empty;
if (string.IsNullOrEmpty(remotePath)) remotePath = ".";
try
{
if (!remotePath.EndsWith("/")) remotePath += "/";
PrivateKeyFile keyFile;
if (!string.IsNullOrEmpty(_passPhrase))
{
keyFile = new PrivateKeyFile(_privateKeyPath, _passPhrase);
}
else
{
keyFile = new PrivateKeyFile(_privateKeyPath);
}
var keyFiles = new[] { keyFile };
using (var client = new SftpClient(_host, _port, _username, keyFiles))
{
client.Connect();
foreach (var filePath in filePathList)
{
using (var fileStream = new FileStream(filePath, FileMode.Open))
{
client.UploadFile(fileStream, remotePath + Path.GetFileName(filePath));
}
}
client.Disconnect();
}
return true;
}
catch (Exception ex)
{
resultMessage = $"SFTPのアップロードでエラーが発生しました。[ファイル:{string.Join(",", filePathList)},リモートパス:{remotePath},エラー内容:{ex.Message}]";
return false;
}
}
public bool Download(string remotePath, string localPath, out string resultMessage)
{
resultMessage = string.Empty;
try
{
var keyFile = new PrivateKeyFile(_privateKeyPath);
var keyFiles = new[] { keyFile };
using (var client = new SftpClient(_host, _port, _username, keyFiles))
{
client.Connect();
using (var fileStream = new FileStream(localPath, FileMode.Create))
{
client.DownloadFile(remotePath, fileStream);
}
client.Disconnect();
}
return true;
}
catch (Exception ex)
{
resultMessage = $"SFTPのダウンロード(Download)でエラーが発生しました。[エラー内容:{ex.Message}]";
return false;
}
}
public bool DownloadMatchingFiles(
string remoteDir,
string localDir,
out int downloadedFileCount,
out string resultMessage,
string pattern = "*.txt")
{
downloadedFileCount = 0;
resultMessage = string.Empty;
if (string.IsNullOrEmpty(remoteDir)) remoteDir = ".";
if (string.IsNullOrEmpty(localDir)) localDir = ".";
if (!Directory.Exists(localDir))
{
resultMessage = $"ダウンロード先のローカルフォルダが存在しません。[ローカルフォルダ:{localDir}]";
return false;
}
try
{
PrivateKeyFile keyFile;
if (!string.IsNullOrEmpty(_passPhrase))
{
keyFile = new PrivateKeyFile(_privateKeyPath, _passPhrase);
}
else
{
keyFile = new PrivateKeyFile(_privateKeyPath);
}
using (var client = new SftpClient(_host, _port, _username, keyFile))
{
client.Connect();
// リモートディレクトリ内のファイル一覧を取得
var files = client.ListDirectory(remoteDir)
.Where(f => !f.IsDirectory && StringUxer.WildcardMatch(f.Name, pattern));
foreach (var file in files)
{
string localPath = Path.Combine(localDir, file.Name);
using (var fs = new FileStream(localPath, FileMode.Create))
{
client.DownloadFile(file.FullName, fs);
Console.WriteLine($"1ファイルダウンロードしました。[ファイル名:{file.Name}]");
downloadedFileCount++;
}
}
client.Disconnect();
}
return true;
}
catch (Exception ex)
{
resultMessage = $"SFTPのダウンロード(DownloadMatchingFiles)でエラーが発生しました。[エラー内容:{ex.Message}]";
return false;
}
}
public bool DeleteMatchingFiles(
string remoteDir,
out int deletedFileCount,
out string resultMessage,
string pattern = "*.txt")
{
deletedFileCount = 0;
resultMessage = string.Empty;
try
{
var keyFile = new PrivateKeyFile(_privateKeyPath, _passPhrase);
using (var client = new SftpClient(_host, _port, _username, keyFile))
{
client.Connect();
// リモートディレクトリ内のファイル一覧を取得
var files = client.ListDirectory(remoteDir)
.Where(f => !f.IsDirectory && StringUxer.WildcardMatch(f.Name, pattern));
foreach (var file in files)
{
string remotePath = PathUxer.CombineUnixPath(remoteDir, file.Name);
client.DeleteFile(remotePath);
deletedFileCount++;
}
client.Disconnect();
}
return true;
}
catch (Exception ex)
{
resultMessage = $"SFTPのファイル削除でエラーが発生しました。[エラー内容:{ex.Message}]";
return false;
}
}
}
}