본문 바로가기
C#, MONO

c#에서 ssh scp로 bash 명령어 실행 및 파일 전송

by gigasound 2021. 8. 11.

 

 

 

 


C#에서 ssh 실행

c#에서 ssh를 실행해서 Raspberry Pi를 조정할 수 있습니다. 또 ssh의 scp를 이용해서 파일 복사도 가능합니다.

먼저 Nuget 패키지 관리자를 이용해서 다음의 내용을 추가합니다.

Renci.ssh.net과 WinSCP의 두 가지 방법으로 실행 방법을 선택해서 적용이 가능합니다.

 


Renci.ssh.net을 이용한 bash 명령어 사용

다음 코드는 ssh로 Raspberry PI로 접근해서 ls -la이라는 명령어를 실행하고 결과를 PC의 콘솔로 출력하는 내용입니다.

다른 명령어를 사용해도 됩니다.

using Renci.SshNet;
using Renci.SshNet.Sftp;
using Renci.SshNet.Common;

SshClient client = new SshClient("192.168.0.**",22,"pi","****");
client.Connect();
if(client.IsConnected == false){ return; }
SshCommand cmd = client.CreateCommand("ls -al");
cmd.Execute();
Console.WriteLine(cmd.Result);
client.Disconnect();

다른 방법으로 using을 사용해도 됩니다.

SshClient client = new SshClient("192.168.0.*",22,"pi","****");
client.Connect();
if(client.IsConnected == false) { return; }
using(SshCommand cmd = client.CreateCommand("ls -al")){
	var asyncExecute = cmd.BeginExecute();
	Console.WriteLine(cmd.Result);
	cmd.EndExecute(asyncExecute);
}

Renci.ssh.net을 이용한 파일 Download Upload

다음 코드와 같이 Renci.ssh.net을 사용하고 ssh 접근 정보와 파일 정보를 선언합니다. 

그리고 UploadFiles(), UploadFiless(), DownloadFile()를 이용해서 파일을 복사합니다. 

using System.IO;
using Renci.SshNet.Sftp;
using Renci.SshNet.Common;
private string host = "192.168.0.*";
private int port = 22;
private string user = "pi";
private string pwd = "****";
private string host_dir = @"/home/pi/";
private string host_file = "t.txt";
private string client_file = @"e:\tt.txt";
string pc_dir = @"E:\tmp";

public void DownloadFiles() {
            using(var client = new SftpClient(host,port,user,pwd)) {
                client.KeepAliveInterval = TimeSpan.FromSeconds(60);
                client.ConnectionInfo.Timeout = TimeSpan.FromMinutes(10);
                client.OperationTimeout = TimeSpan.FromMinutes(180);
                client.Connect();
                if(client.IsConnected == false) { return; }
                //-현재 디렉코리
                //foreach(SftpFile f in client.ListDirectory(".")){
                //    Console.WriteLine(f.Name);
                //}
                //-download
                using(var outfile = File.Create(host_file)){
                    client.DownloadFile(host_file,outfile);
                }
                client.Disconnect();
            }//-using
        }

        public void DownloadFile() {
            using(var client = new SftpClient(host,port,user,pwd)) {
                client.KeepAliveInterval = TimeSpan.FromSeconds(60);
                client.ConnectionInfo.Timeout = TimeSpan.FromMinutes(10);
                client.OperationTimeout = TimeSpan.FromMinutes(180);
                client.Connect();
                if(client.IsConnected == false){ return; }
                var file = client.ListDirectory(host_dir).FirstOrDefault(f => f.Name == host_file);
                if(file != null){
                    using(Stream fs = File.OpenWrite(Path.Combine(pc_dir,file.Name))){
                        client.DownloadFile(file.FullName,fs);
                    }
                }
                client.Disconnect();
            }//-using
        }

        /// <summary>
        /// linux의 경로는 usr의 접근 귄한이 잇어야 한다. 
        /// </summary>
        public void UploadFiles(){
            using(var client = new SftpClient(host,port,user,pwd)) {
                client.KeepAliveInterval = TimeSpan.FromSeconds(60);
                client.ConnectionInfo.Timeout = TimeSpan.FromMinutes(10);
                client.OperationTimeout = TimeSpan.FromMinutes(180);
                client.Connect();
                if(client.IsConnected == false) { return; }
                client.ChangeDirectory(host_dir);

                using(var infile = File.Open(this.client_file, FileMode.Open)){
                    client.UploadFile(infile,"tt.txt");
                }
                client.Disconnect();
            }
        }

        /// <summary>
        /// linux의 경로는 usr의 접근 귄한이 있어야 한다. 
        /// </summary>
        public void UploadFile() {
            using(var client = new SftpClient(host,port,user,pwd)) {
                client.KeepAliveInterval = TimeSpan.FromSeconds(60);
                client.ConnectionInfo.Timeout = TimeSpan.FromMinutes(10);
                client.OperationTimeout = TimeSpan.FromMinutes(180);
                client.Connect();
                if(client.IsConnected == false) { return; }
                client.ChangeDirectory(host_dir);
                //var listDir = client.ListDirectory(host_dir);
                //foreach(var fi in listDir) {
                //    Console.WriteLine(" - " + fi.Name);
                //}
                using(var fs = new FileStream(client_file,FileMode.Open)) {
                    //client.BufferSize = 4 * 1024;
                    client.UploadFile(fs,Path.GetFileName(client_file));
                }
                client.Disconnect();
            }
        }

WinSCP로 bash 명령어 사용

원도우즈에서 리룩스로 파일을 송수신하는 프로그램인 WinSCP.exe를 c#에서 사용할 수 있습니다. 

위의 글의 내용과 같이 Nuget으로 WinSCP를 설치해야 합니다. 그리고 다음과 같이 cmd에 명령어를 만들어 입력해서 실행하면 됩니다. 

ssh.net 방법과는 좀 다르고 실행 결과가 보이지 않습니다. 

using WinSCP;

public int WinSCP_Command(string cmd) {
	try {
		// Setup session options
		WinSCP.SessionOptions sessionOptions = new WinSCP.SessionOptions {
			Protocol = WinSCP.Protocol.Sftp,
			HostName = this.ssh_addres,
			UserName = this.ssh_user,
			Password = this.ssh_pwd,
		};
		using(WinSCP.Session session = new WinSCP.Session()) {
			session.Open(sessionOptions);
			session.ExecuteCommand(cmd).Check();
		}
		return 0;
	}
	catch(Exception e) {
		Console.WriteLine("Error: {0}",e);
		return 1;
	}
}

WinSCP로 파일 Download Upload

using WinSCP;

static void UploadFile(){
	using(Session session = new Session()) {
		Console.WriteLine("Upload start.");
		var sessionOptions = new SessionOptions {
          Protocol = Protocol.Sftp,
          HostName = "192.168.0.*",
          UserName = "pi",
          Password = "****",
          GiveUpSecurityAndAcceptAnySshHostKey = true
    	};
    	session.Open(sessionOptions);
    	var txOptions = new TransferOptions();
        txOptions.TransferMode = TransferMode.Binary;
        TransferOperationResult txResult;
        txResult = session.PutFiles(@"e:\tt.txt","/home/pi/",false,txOptions);
        txResult.Check();
        Console.WriteLine("Upload end.");
	}
}

static void DownFile() {
    using(Session session = new Session()) {
    Console.WriteLine("Download start.");
    var sessionOptions = new SessionOptions {
        Protocol = Protocol.Sftp,
        HostName = "192.168.0.*",
        UserName = "pi",
        Password = "***",
        GiveUpSecurityAndAcceptAnySshHostKey = true
    };
    session.Open(sessionOptions);
    var txOptions = new TransferOptions();
    txOptions.TransferMode = TransferMode.Binary;
    TransferOperationResult txResult;
    txResult = session.GetFiles("/home/pi/t.txt",@"e:\",false);
    txResult.Check();
    Console.WriteLine("Download end.");
    }
}

광고좀 꾹 눌러주시면 고맙겠습니다. 


위의 내용을 참조용으로만 사용해주세요. 무단 도용이나 무단 복제는 불허합니다.

기타 문의 사항은 gigasound@naver.com에 남겨 주시면 고맙겠습니다.

'C#, MONO' 카테고리의 다른 글

프로그램 중복 실행 방지하기  (0) 2021.08.14
로그(Log) 를 남기고, 오래된 로그 파일 자동 삭제  (0) 2021.08.14
c#과 Python의 연동  (1) 2021.08.11
Enum의 정보 변환 하기  (0) 2021.08.11
문장 변환 정리(1)  (0) 2021.08.11