0

I know that this question was answered many times and the solution that I have works almost in all cases except for one.

The code in question is this:

Path.GetFullPath(Path.Combine(rootFolder, relativeFilePath))

It works great most of the time even with messy relative paths, UNC and absolute paths as shown below:

// These results are OK
Path.GetFullPath(Path.Combine(@"a:\b\c", @"e.txt"));    // Returns: "a:\b\c\e.txt"
Path.GetFullPath(Path.Combine(@"a:\b\c", @"..\e.txt")); // Returns: "a:\b\e.txt" 
Path.GetFullPath(Path.Combine(@"a:\b\c", @"d:\e.txt")); // Returns: "d:\e.txt"

However in this case it does not work as expected:

Path.GetFullPath(Path.Combine(@"a:\b\c", @"\e.txt"))

Expected result is "a:\e.txt" but the code returns "c:\e.txt". "c:" is the current drive so it solves the part of the puzzle but why is this happening? Is there another way to get the full path that works in all cases?

Edit: Based on info from answers here is the solution that works. May need some null checking and alternative directory separator char checking though:

var rootDir = @"a:\b\c";
var filePath = @"\e.txt";
var result = (Path.IsPathRooted(filePath) && 
    Path.GetPathRoot(filePath) == Path.DirectorySeparatorChar.ToString()) ?
    Path.GetFullPath(Path.Combine(Path.GetPathRoot(rootDir), filePath.Substring(1))) :
    Path.GetFullPath(Path.Combine(rootDir, filePath));
Optional Option
  • 1,521
  • 13
  • 33

2 Answers2

5

As written in the documentation:

If path2 includes a root, path2 is returned.

The fact that path2 begins with slash makes it a root.

Also, in Path.GetFullPath:

This method uses current directory and current volume information to fully qualify path. If you specify a file name only in path, GetFullPath returns the fully qualified path of the current directory.

Kenneth K.
  • 2,987
  • 1
  • 23
  • 30
1

As per the documentation:

If path2 includes a root, path2 is returned.

Looking at the reference source we can see that if a path starts with a "\" then it is considered to contain a root.

// Tests if the given path contains a root. A path is considered rooted
// if it starts with a backslash ("\") or a drive letter and a colon (":").
//
[Pure]
public static bool IsPathRooted(String path) {
    if (path != null) {
        CheckInvalidPathChars(path);

        int length = path.Length;
        if ((length >= 1 && (path[0] == DirectorySeparatorChar || path[0] == AltDirectorySeparatorChar)) || (length >= 2 && path[1] == VolumeSeparatorChar))
             return true;
    }
    return false;
}
Owen Pauling
  • 11,349
  • 20
  • 53
  • 64
  • Looks like Boolean answer is just too simple for paths :) I would not consider \somepath rooted but then it could be the bug so old that it has become the feature. – Optional Option Jul 12 '18 at 17:47