C#开发-连接SSH

SSH.NET

安装库

1
Install-Package SSH.NET

执行命令

这种方式执行命令时可能并不会像在实际的交互式 shell 中那样完全保留命令之间的状态。

cd 命令通常只在当前的 shell 会话中临时改变工作目录,并不会永久地改变服务器的全局工作目录设置,

所以当你执行下一个命令时,它会在一个新的 shell 会话中执行,而不是在 cd 命令修改后的会话中执行。

执行命令

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
private void ConnectSSH()
{
var connectionInfo = new PasswordConnectionInfo("110.110.110.110", "root", "123456");
using (var sshClient = new SshClient(connectionInfo))
{
sshClient.Connect();
if (sshClient.IsConnected)
{
var cmd = sshClient.CreateCommand("ls -la"); // 替换为你想执行的命令
var result = cmd.Execute();
Debug.WriteLine(result);
}

sshClient.Disconnect();
}
}

交互式的 Shell 流

允许你与远程服务器进行类似在命令行终端中进行的交互式操作。通过这个 shell 流,你可以发送命令并接收服务器的响应,就像在实际的终端中一样。例如,你可以逐步输入命令,查看每个命令的输出,以及根据前面命令的结果决定下一个命令的输入。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
PasswordConnectionInfo connectionInfo = new(
host,
username,
password
);
_sshClient = new SshClient(connectionInfo);
_sshClient.Connect();
_shellStream = _sshClient.CreateShellStream(
"dumb",
80,
24,
800,
600,
1024
);

// 读取输出
new Thread(
o =>
{
while (IsConnect)
{
while (_shellStream.DataAvailable || !_shellStream.CanRead)
{
_outAction.Invoke(_shellStream.Read());
}
}
}
) { IsBackground = true }.Start();

获取文件列表

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
private void GetFileList()
{
if (_sshClient == null || !_sshClient.IsConnected)
{
return;
}
using SftpClient sftp = new SftpClient(_sshClient.ConnectionInfo);
sftp.Connect();
IEnumerable<ISftpFile> fileList = sftp.ListDirectory("/etc/nginx/");
List<ISftpFile> sortedList = fileList.OrderBy(item => item.IsDirectory ? 0 : 1).ThenBy(item => item.Name).ToList();
foreach (ISftpFile item in sortedList)
{
if (item.Name == ".." || item.Name == ".")
{
continue;
}
if (item.IsDirectory)
{
Debug.WriteLine($"{item.Name} 是文件夹。");
}
else
{
Debug.WriteLine($"{item.Name} 是文件。");
}
}
}

判断是否存在

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
public bool IsFolderExist(string pathToCheck)
{
if (_sftp is not { IsConnected: true })
{
return false;
}
bool pathExists;
try
{
_sftp.GetAttributes(pathToCheck);
pathExists = true;
}
catch (SftpPathNotFoundException)
{
pathExists = false;
}
return pathExists;
}

Putty

https://www.chiark.greenend.org.uk/~sgtatham/putty/latest.html

命令行调用

1
putty.exe -ssh root@39.104.203.241 -P 22