Best/Easiest/Quickest way to get relative path bet

2020-07-22 17:27发布

问题:

I'm in the midst of some refactoring some C# code and part of this is to redo some references, because we're redoing the folder structure entirely. What I'd like to do is just go into the .csproj or .sln file and modify the paths.

However some of the references have paths like

"../../../../../../ThirdParty/SomeMicrosoftLibrary/bin/Debug/SomeMicrosoftLibrary.dll

And since we've moved everything around I need to find the new relative path. But I absolutely hate trying to do this (figure out how many slashes and periods I need to put in) since it always feels like some hit or miss science.

Is there some easy way (utility, script, snippet of code) to say "here's file A, here's file B, what is the relative path of file B in relation to file A?"

回答1:

Generate a Relative Path

It's in Java, but easily translatable to C#.



回答2:

With Ruby:

$ ruby -e "require 'pathname'; puts Pathname.new('foo/bar').relative_path_from(Pathname.new('baz/x/y/z')).to_s"
../../../../foo/bar

I'm pretty sure Python has a similar method, though I don't have it handy.



回答3:

I know this is old but I was looking for the answer to this so here's a method which does it, just in case it might help anyone else out in the future

/// <summary>
/// Finds the relative path of B with respect to A
/// </summary>
/// <param name="A">The path you're navigating from</param>
/// <param name="B">The path you're navigating to</param>
/// <returns></returns>
static string Get_PathB_wrt_PathA(string A, string B)
{
    string result = "";

    if (A == B)
        return result;

    var s = new char[] { '\\' };
    var subA = A.Split(s, StringSplitOptions.RemoveEmptyEntries).ToList();
    var subB = B.Split(s, StringSplitOptions.RemoveEmptyEntries).ToList();

    int L = subA.Count >= subB.Count ? subB.Count : subA.Count;
    int i = 0;

    for (i = 0; i < L; i++)
    {
        if (subA[0] == subB[0])
        {
            subA.RemoveAt(0);
            subB.RemoveAt(0);
        }
        else
            break;
    }

    for (i = 0; i <= subA.Count - 1; i++)
    {
        result += @"..\"; //this navigates to the preceding directory
    }

    for (i = 0; i < subB.Count; i++)
    {
        result += subB[i] + "\\";
    }

    result = result.Substring(0, result.Length - 1); //remove the extra backslash
    return result;
}