简体   繁体   中英

Renci SSH.NET: How to delete nonempty directory?

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?

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)

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(); Renci.SshClient ssh1 = new SshCLient("server","user","password"); ssh1.connect(); ssh1.RunCommand("cd LandingZone;rm -rf <directoryName>"); ssh1.Disconnect();

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;
    }

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM