Reputation: 2436
I am using Renci SSH.NET to access files and folders on a unix server. I would like to delete a whole directory tree by specifying the base directory, but when I call sftp.DeleteDirectory(destination)
, that call will only succeed if I pass an empty directory.
However, I would also like to be able to delete directories containing files or additional folders. Most .NET classes will handle that automatically, how can it be done in SSH.NET?
Upvotes: 7
Views: 7398
Reputation: 135
Try executing the command in SSH instead of using sftp rm -rf or rm -r.
Code may look something like this:
Renci.SshClient ssh1 = new SshCLient("server","user","password");
ssh1.connect();
ssh1.RunCommand("cd LandingZone;rm -rf <directoryName>");
ssh1.Disconnect();
Upvotes: 3
Reputation: 202504
The SSH.NET library does not support any recursive operations. So recursive delete is not available either.
You have to use the SftpClient.ListDirectory
method to recursively list all files and subfolders and delete them one by one.
private static void DeleteDirectory(SftpClient client, string path)
{
foreach (SftpFile file in client.ListDirectory(path))
{
if ((file.Name != ".") && (file.Name != ".."))
{
if (file.IsDirectory)
{
DeleteDirectory(client, file.FullName);
}
else
{
client.DeleteFile(file.FullName);
}
}
}
client.DeleteDirectory(path);
}
Or use another SFTP library.
For example with WinSCP .NET assembly, you can use the Session.RemoveFiles
method that can delete a directory recursively.
// Setup session options
SessionOptions sessionOptions = new SessionOptions
{
Protocol = Protocol.Sftp,
HostName = "example.com",
UserName = "user",
Password = "mypassword",
SshHostKeyFingerprint = "ssh-rsa 2048 xxxxxxxxxxx...="
};
using (Session session = new Session())
{
// Connect
session.Open(sessionOptions);
// Delete the directory recursively
session.RemoveFiles("/directory/to/delete").Check();
}
WinSCP GUI can generate a code template for you.
(I'm the author of WinSCP)
Upvotes: 17
Reputation: 1
You can delete a directory tree or a file dynamically using SSH.NET library (regardless if it is an empty directory or not) by specifying the remote path with these two methods:
public bool DeleteRemoteDirectoryRecursive(string RemoteDirectoryPath)
{
if (string.IsNullOrEmpty(RemoteDirectoryPath))
{
return false;
}
var ConnectionInfo = new ConnectionInfo(this.sftpHost, this.sftpPort, this.sftpUser, new PasswordAuthenticationMethod(this.sftpUser, this.sftpPassword));
using (var client = new SftpClient(ConnectionInfo))
{
client.Connect();
if (!client.Exists(RemoteDirectoryPath))
{
client.Disconnect();
client.Dispose();
return false;
}
foreach (var file in client.ListDirectory(RemoteDirectoryPath))
{
if (file.Name.Equals(".") || file.Name.Equals(".."))
continue;
if (file.IsDirectory)
{
client.Disconnect();
DeleteRemoteDirectoryRecursive(file.FullName);
}
else
client.DeleteFile(file.FullName);
}
client.DeleteDirectory(RemoteDirectoryPath);
}
return true;
}
public bool Remove(string RemotePath)
{
bool ReturnResult = false;
try
{
if (string.IsNullOrEmpty(RemotePath))
{
return false;
}
var ConnectionInfo = new ConnectionInfo(this.sftpHost, this.sftpPort, this.sftpUser, new PasswordAuthenticationMethod(this.sftpUser, this.sftpPassword));
using (var client = new SftpClient(ConnectionInfo))
{
client.Connect();
if (!client.Exists(RemotePath))
{
client.Disconnect();
client.Dispose();
return false;
}
try
{
// path is directory
client.ChangeDirectory(RemotePath);
try
{
DeleteRemoteDirectoryRecursive(RemotePath);
ReturnResult = true;
}
catch
{
ReturnResult = false;
}
}
// path is a file
catch
{
try
{
client.DeleteFile(RemotePath);
ReturnResult = true;
}
catch
{
ReturnResult = false;
}
}
}
}
catch (Exception ex)
{
ReturnResult = false;
}
return ReturnResult;
}
Upvotes: -2