19

I have 2 Files:

C:\Program Files\MyApp\images\image.png

C:\Users\Steve\media.jpg

Now i want to calculate the File-Path of File 2 (media.jpg) relative to File 1:

..\..\..\Users\Steve\

Is there a built-in function in .NET to do this?

0xDEADBEEF
  • 3,401
  • 8
  • 37
  • 66

2 Answers2

22

Use:

var s1 = @"C:\Users\Steve\media.jpg";
var s2 = @"C:\Program Files\MyApp\images\image.png";

var uri = new Uri(s2);

var result = uri.MakeRelativeUri(new Uri(s1)).ToString();
Kirill Polishchuk
  • 54,804
  • 11
  • 122
  • 125
  • 1
    It should be pointed out that when using this method that the relative path which will be given is going to have '/' instead of '\'. The output would give: ../../..Users/Steve/ A simple replace will correct this for file pathing. – Mike G Dec 18 '12 at 13:35
  • This does not handle all edge cases. See [this](http://stackoverflow.com/questions/275689/how-to-get-relative-path-from-absolute-path/32113484#32113484) answer. – Muhammad Rehan Saeed Aug 20 '15 at 10:41
4

There is no built-in .NET, but there is native function. Use it like this:

[DllImport("shlwapi.dll", CharSet=CharSet.Auto)]
static extern bool PathRelativePathTo(
     [Out] StringBuilder pszPath,
     [In] string pszFrom,
     [In] FileAttributes dwAttrFrom,
     [In] string pszTo,
     [In] FileAttributes dwAttrTo
);

Or if you still prefer managed code then try this:

    public static string GetRelativePath(FileSystemInfo path1, FileSystemInfo path2)
    {
        if (path1 == null) throw new ArgumentNullException("path1");
        if (path2 == null) throw new ArgumentNullException("path2");

        Func<FileSystemInfo, string> getFullName = delegate(FileSystemInfo path)
        {
            string fullName = path.FullName;

            if (path is DirectoryInfo)
            {
                if (fullName[fullName.Length - 1] != System.IO.Path.DirectorySeparatorChar)
                {
                    fullName += System.IO.Path.DirectorySeparatorChar;
                }
            }
            return fullName;
        };

        string path1FullName = getFullName(path1);
        string path2FullName = getFullName(path2);

        Uri uri1 = new Uri(path1FullName);
        Uri uri2 = new Uri(path2FullName);
        Uri relativeUri = uri1.MakeRelativeUri(uri2);

        return relativeUri.OriginalString;
    }
Tomislav Markovski
  • 12,331
  • 7
  • 50
  • 72