Search code examples
c#.netfilefilepath

Why Get A Relative Path From One To Another Working Not Correct?


guys i tried this one:

current: \netcoreapp2.1\ResultPath

target : \netcoreapp2.1\ReportPath\report1

   AssemblyDirectory = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);

   Uri currentPath = new Uri(AssemblyDirectory + "//ResultPath");
   Uri targetPath = new Uri(reportsSubDir);

   Uri relPath = currentPath.MakeRelativeUri(targetPath);

In result i'm getting

relPath.OriginalString = ReportPath/report1

Why is not ../ReportPath/report1 ?

And now for example:

if i have

current: \netcoreapp2.1\ResultPath\Test

target : \netcoreapp2.1\ReportPath\report1

I'm getting correct result in this way

relPath.OriginalString = ../../ReportPath/report10

Could anyone explain me why in first step i'm getting bad Relative Path, but in second good

and any idea how can i fix it, if i want to use first and second examples in my way ?


Solution

  • Well, if you are using .NET 5, you're in luck, since new method was included: Path.GetRelativePath(string, string)

    If not, we can always dig into MS .NET Framework code:

    https://referencesource.microsoft.com/#System.Workflow.ComponentModel/AuthoringOM/Design/DesignerHelpers.cs,a561eb779ce7163d

    And copy implementation, which is:

    static class PathHelper
     {
         internal static string GetRelativePath(string pathFrom, string pathTo)
         {
             Uri uri = new Uri(pathFrom);
             string relativePath = Uri.UnescapeDataString(uri.MakeRelativeUri(new Uri(pathTo)).ToString());
             relativePath = relativePath.Replace(Path.AltDirectorySeparatorChar, Path.DirectorySeparatorChar);
             if (!relativePath.Contains(Path.DirectorySeparatorChar.ToString()))
                 relativePath = "." + Path.DirectorySeparatorChar + relativePath;
             return relativePath;
         }
     }
    

    Usage then would be:

    var p1 = @"C:\users\turek\source\";
    var p2 = @"C:\users\turek\desktop\";
    
    PathHelper.GetRelativePath(p1, p2);
    // returns "..\\desktop\\"