There's a part in my apps that displays the file path loaded by the user through OpenFileDialog. It's taking up too much space to display the whole path, but I don't want to display only the filename as it might be ambiguous. So I would prefer to show the file path relative to the assembly/exe directory.
For example, the assembly resides at "C:\Program Files\Dummy Folder\MyProgram" and the file at "C:\Program Files\Dummy Folder\MyProgram\Data\datafile1.dat" then I would like it to show ".\Data\datafile1.dat". If the file is in "C:\Program Files\Dummy Folder\datafile1.dat", then I would want "..\datafile1.dat". But if the file is at the root directory or 1 directory below root, then display the full path.
What solution would you recommend? Regex?
Basically I want to display useful file path info without taking too much screen space.
EDIT: Just to clarify a little bit more. The purpose of this solution is to help user or myself knowing which file did I loaded last and roughly from which directory was it from. I'm using a readonly textbox to display the path. Most of the time, the file path is much longer than the display space of the textbox. The path is supposed to be informative but not important enough as to take up more screen space.
Alex Brault comment was good, so is Jonathan Leffler. The Win32 function provided by DavidK only help with part of the problem, not the whole of it, but thanks anyway. As for James Newton-King solution, I'll give it a try later when I'm free.
If you know that toPath is contained by fromPath then you can keep it simple. I'll leave out the asserts for brevity.
I'm using this:
As Alex Brault points out, especially on Windows, the absolute path (with drive letter and all) is unambiguous and often better.
Shouldn't your OpenFileDialog use a regular tree-browser structure?
To get some nomenclature in place, the RefDir is the directory relative to which you want to specify the path; the AbsName is the absolute path name that you want to map; and the RelPath is the resulting relative path.
Take the first of these options that matches:
To illustrate the last rule (which is, of course, by far the most complex), start with:
Then
While I was typing, DavidK produced an answer which suggests that you are not the first to need this feature and that there is a standard function to do this job. Use it. But there's no harm in being able to think your way through from first principles, either.
Except that Unix systems do not support drive letters (so everything is always located under the same root directory, and the first bullet therefore is irrelevant), the same technique could be used on Unix.
I'd split both of your paths at the directory level. From there, find the point of divergence and work your way back to the assembly folder, prepending a '../' everytime you pass a directory.
Keep in mind however, that an absolute path works everywhere and is usually easier to read than a relative one. I personally wouldn't show an user a relative path unless it was absolutely necessary.
The function that uses URI returned "almost" relative path. It included directory that directly contains the file which relative path I wanted to get.
Some time ago I wrote a simple function that returns relative path of folder or file, and even if it's on another drive, it includes the drive letter as well.
Please take a look:
Way with Uri not worked on linux/macOS systems. Path '/var/www/root' can't be converted to Uri. More universal way - do all by hands.
PS: i use "/" as a default value of separator instead of Path.DirectorySeparatorChar, because result of this method used as uri in my app.