0

I have a question that I have no idea how to ask in a simple way so I will do and introduction fist and the question at the end I hope that you get the idea

Using RemoteFileInfo C# class you get the files in the location and two additional records parent directory and current directory.

Searching on “/” I will get:

 /.. parent directory 
 /. Current directory 
 /Test  file folder fullname 
 /Test2 file folder fullname

If in the same Session I move forward to the Test folder using “/Test” I get:

/TEST/.. parent directory
/TEST/. Current directory
/TEST/New folder   file folder full name
/TEST/New folder2 file folder full name

If in the same Session I go back to the previous folder using the parent directory “/TEST/..” I get:

/TEST/./../.. parent directory
/TEST/./../. current directory

/TEST/./../.. file folder full name
/TEST2/./../.. file folder full name

If in the same Session I go forward again to Test Folder using the test folder full name “/TEST/./../TEST” that I get on the previous result I get:

/TEST/./../TEST/.. parent directory
/TEST/./../TEST/. current directory

/TEST/./../TEST/New folder
/TEST/./../TEST/New folder2

If I keep back and forward in the same Session using the parent fullname or the file folder fullname it works it moves to the right location but each time the fullname keep growing with the previous fullname on it. if there a way I can get a single path when moving back and forward? Like when I go to the “/” after moving back and forward I get:

/.. parent directory
/. Current directory
/Test  file folder full name
/Test2 file folder full name

I’m doing a single file explorer interface and I want to show the user the current path but is confusing showing something like this /TEST/./../TEST/New folder as current location.

Please let me know if better explanation is need it ;)

I made Minimal Reproducible Example using C# Console Application.

 class Program
    {
        static Session session = new Session();
        static void Main(string[] args)
        {
            var l = new List<DirectoryInformation>();
            string GoToThisDirectory = "";

            //OPEN SESSION
            SessionIni();

            //Get File information for the Root folder
            Console.WriteLine("ROOT FOLDER");

            l = GetDirFiles("/TEST");
            foreach (var item in l)
            {
                // let's take the fist directory that is not this directory to move to that one next time
                if (item.IsThisDirectory == false)
                {
                    GoToThisDirectory = item.FullName;
                }

                //Display the current directory
                if (item.IsThisDirectory == true)
                {
                    Console.WriteLine(string.Concat("CURRENT FOLDER: ", item.FullName));
                }
                Console.WriteLine(string.Concat(" FullName: ", item.FullName,
                    " IsDirectory: ", item.IsDirectory,
                    " IsThisDirectory: ", item.IsThisDirectory,
                    " IsParentDirectory: ", item.IsParentDirectory));
            }
            Console.WriteLine();

            l = GetDirFiles(GoToThisDirectory);
            Console.WriteLine("MOVE FORWARD TO LEVEL1 FOLDER");
            foreach (var item in l)
            {
                // let's take the parent directory folder to move to that one next time
                if (item.IsParentDirectory == true)
                {
                    GoToThisDirectory = item.FullName;
                }
                if (item.IsThisDirectory == true)
                {
                    Console.WriteLine(string.Concat("CURRENT FOLDER: ", item.FullName));
                }
                Console.WriteLine(string.Concat(" FullName: ", item.FullName,
                    " IsDirectory: ", item.IsDirectory,
                    " IsThisDirectory: ", item.IsThisDirectory,
                    " IsParentDirectory: ", item.IsParentDirectory));
            }

            Console.WriteLine();

            l = GetDirFiles(GoToThisDirectory);
            Console.WriteLine("MOVE BACK TO PARENT DIRECTORY FOLDER");
            foreach (var item in l)
            {
                // let's take the fist directory that is not this directory to move to that one again
                if (item.IsThisDirectory == false)
                {
                    GoToThisDirectory = item.FullName;
                }
                if (item.IsThisDirectory == true)
                {
                    Console.WriteLine(string.Concat("CURRENT FOLDER: ", item.FullName));
                }
                Console.WriteLine(string.Concat(" FullName: ", item.FullName,
                    " IsDirectory: ", item.IsDirectory,
                    " IsThisDirectory: ", item.IsThisDirectory,
                    " IsParentDirectory: ", item.IsParentDirectory));
            }

            Console.WriteLine();


            l = GetDirFiles(GoToThisDirectory);
            Console.WriteLine("MOVE BACK AGAIN TO LEVEL1 FOLDER");
            foreach (var item in l)
            {
                if (item.IsThisDirectory == true)
                {
                    Console.WriteLine(string.Concat("CURRENT FOLDER: ", item.FullName));
                }
                Console.WriteLine(string.Concat(" FullName: ", item.FullName,
                    " IsDirectory: ", item.IsDirectory,
                    " IsThisDirectory: ", item.IsThisDirectory,
                    " IsParentDirectory: ", item.IsParentDirectory));
            }
            Console.Read();
        }

        private static void SessionIni()
        {
            SessionOptions sessionOptions = new SessionOptions
            {
                Protocol = Protocol.Sftp,
                HostName = "XX.XX.XX.XX",
                UserName = "UserName",
                Password = "Password",
                SshHostKeyFingerprint = "XXXXXXXXXXXXXXX",
            };
            session.Open(sessionOptions);
        }
        private static List<DirectoryInformation> GetDirFiles(string dir)
        {
            var l = new List<DirectoryInformation>();
            RemoteDirectoryInfo directory = session.ListDirectory(dir);

            foreach (RemoteFileInfo fileInfo in directory.Files)
            {
                l.Add(new DirectoryInformation
                {
                    Name = fileInfo.Name,
                    FullName = fileInfo.FullName,
                    IsDirectory = fileInfo.IsDirectory,
                    IsThisDirectory = fileInfo.IsThisDirectory,
                    IsParentDirectory = fileInfo.IsParentDirectory,
                });
            }
            return l;
        }
    }
    class DirectoryInformation
    {
        public string Name { get; set; }
        public string FullName { get; set; }
        public bool IsDirectory { get; set; }
        public bool IsThisDirectory { get; set; }
        public bool IsParentDirectory { get; set; }
    }

Console Read:

ROOT FOLDER
CURRENT FOLDER: /TEST/.
 FullName: /TEST/. IsDirectory: True IsThisDirectory: True IsParentDirectory: False
 FullName: /TEST/.. IsDirectory: True IsThisDirectory: False IsParentDirectory: True
 FullName: /TEST/Level1 IsDirectory: True IsThisDirectory: False IsParentDirectory: False

MOVE FORWARD TO LEVEL1 FOLDER
CURRENT FOLDER: /TEST/Level1/.
 FullName: /TEST/Level1/. IsDirectory: True IsThisDirectory: True IsParentDirectory: False
 FullName: /TEST/Level1/.. IsDirectory: True IsThisDirectory: False IsParentDirectory: True
 FullName: /TEST/Level1/Level2 IsDirectory: True IsThisDirectory: False IsParentDirectory: False

MOVE BACK TO PARENT DIRECTORY FOLDER
CURRENT FOLDER: /TEST/Level1/../.
 FullName: /TEST/Level1/../. IsDirectory: True IsThisDirectory: True IsParentDirectory: False
 FullName: /TEST/Level1/../.. IsDirectory: True IsThisDirectory: False IsParentDirectory: True
 FullName: /TEST/Level1/../Level1 IsDirectory: True IsThisDirectory: False IsParentDirectory: False

MOVE BACK AGAIN TO LEVEL1 FOLDER
CURRENT FOLDER: /TEST/Level1/../Level1/.
 FullName: /TEST/Level1/../Level1/. IsDirectory: True IsThisDirectory: True IsParentDirectory: False
 FullName: /TEST/Level1/../Level1/.. IsDirectory: True IsThisDirectory: False IsParentDirectory: True
 FullName: /TEST/Level1/../Level1/Level1 IsDirectory: True IsThisDirectory: False IsParentDirectory: False

The last current forlder shows:

CURRENT FOLDER: /TEST/Level1/../Level1/.

and I wish to get

/TEST/Level1/
Albert Torres
  • 163
  • 2
  • 15
  • What does it mean *"If in the same Session I move forward"* - What API do you use for that? + In any case, you should resolve the `.` and `..` in your code. – Martin Prikryl Nov 20 '19 at 15:29
  • I use Assembly WinSCPnet, Version=1.6.5.9925 and what I mean for Session is a WinSCP.Session() after open the session it keep open and every time I move back or forward I use it in here “RemoteDirectoryInfo directory = session.ListDirectory(dir)”; and I want to display the current directory using the Current Directory Fullname value property return and there is where I get the /TEST/./../TEST/New folder depend on how many time I have moved. Hope make sense. – Albert Torres Nov 20 '19 at 16:06
  • So do you mean that you do `session.ListDirectory("/some/path/..")` and then you get entries with `FullPath` being like `"/some/path/../file"`. Correct? – Martin Prikryl Nov 20 '19 at 16:12
  • Yes and depending how many time I move back and forward I get Fullname like this "/TEST/./../TEST/New folder" and in this particular one I need to show to the user that you are on "/Test/New Folder" and I want if it's possible to get that value from the current directory fullname value – Albert Torres Nov 20 '19 at 16:25

1 Answers1

0

Do not blindly concatenate the paths.

Process the . and .. in your code.

In general, the . entry should be ignored. It is hardly useful for the end user.

And for the .., instead of trying to access the /base/path/subfolder/.. go up to /base/path.

Martin Prikryl
  • 188,800
  • 56
  • 490
  • 992
  • I don't do any blindly concatenate paths I use what is return on the fullname value to send that to the session.ListDirectory() and that works perfect. I just want to use the value on the current directory fullname property to display that to the user. – Albert Torres Nov 20 '19 at 16:29
  • Then I probably do not understand what are you doing. We need [mcve]. – Martin Prikryl Nov 20 '19 at 16:30
  • No problem, I will do that and posted as soon as possible. – Albert Torres Nov 20 '19 at 16:36
  • I edit the original question and add the minimal reproducible example. – Albert Torres Nov 20 '19 at 18:00
  • OK, so you expect the `FullName` for the `..` entry of directory `/remote/path` to return `/remote` and not `/remote/path/..`, right? – Martin Prikryl Nov 20 '19 at 18:45
  • I expect to get this /TEST/Level1/ not this /TEST/Level1/../Level1/. – Albert Torres Nov 20 '19 at 18:50
  • 1
    OK. But it does not work like that. This is not a kind of question you should ask on SO. If you confider this a bug, you should report it on WinSCP site. – Martin Prikryl Nov 20 '19 at 18:57
  • But it’s there are reason why it works this way? At some point I could get values like /TEST/Level1/../Level1/../Level1/../Level1/../Level1/.. if I keep back and forward. I will post this on WinSCP site as you suggest thanks for your time. – Albert Torres Nov 20 '19 at 19:17
  • The reason is simple, the `FullPath` returns the path you pass to `ListDirectory` concatenated with the file/entry name. I would not expect anyone to use `FullPath` property of the `..` entry. No one uses the `..` entry. – Martin Prikryl Nov 20 '19 at 20:07