如何在Windows应用程序中将相对路径转换为绝对路径?


89

如何在Windows应用程序中将相对路径转换为绝对路径?

我知道我们可以在ASP.NET中使用server.MapPath()。但是我们可以在Windows应用程序中做什么?

我的意思是,如果有一个.NET内置函数可以处理该问题...


2
您是指当前目录的相对路径,换句话说是工作目录,还是相对于.exe位置的相对路径?
Tobias Hertkorn 09年

2
相对路径有两种。一个if的形式为“ A \ B \ C”,并不表示特定的底数。另一个的格式为“。\ A \ B”或“ .. \ A \ B”;这些是相对于当前工作目录的。
MSalters

1
@Amit Dhall:顺便说一句,接受并支持对您有帮助的答案是一件好事。
Francis B.

Answers:


180

你有没有尝试过:

string absolute = Path.GetFullPath(relative);

?请注意,这将使用进程的当前工作目录,而不是包含可执行文件的目录。如果那没有帮助,请澄清您的问题。


3
这是否取决于您从哪里启动应用程序,而不取决于exe文件所在的位置?当然,这个问题还不是很清楚。
Tobias Hertkorn 09年

1
正如您所说,问题尚不清楚。GetFullPath将从当前工作目录解析。我将编辑我的回复以表明这一点。
乔恩·斯基特

1
如果应用程序是通过Windows资源管理器启动的,则当前目录和正在执行的程序集目录似乎是相同的(至少在进行某些操作以使它们不同之前)。即使您对可执行文件使用快捷方式,而该快捷方式位于完全不同的位置,也是如此。
H2ONaCl

19

如果要获取相对于.exe的路径,请使用

string absolute = Path.Combine(Application.ExecutablePath, relative);

4
请注意Path.Combine。如果“相对”部分以斜杠开头,则可能无法达到您的预期。
中午丝绸

2
@silky:好吧,那不是相对的,对吗?
Tor Haugen

1
似乎Path.Combine甚至无法处理驱动器相对路径。它只是忽略了看起来的初始路径。我正在发布自己的完整解决方案。
Nyerguds

3
这无法处理相对路径。它仅接受目录和文件名。如果第二个参数以开头..,则会产生垃圾。
乔纳森·伍德

1
@JonathanWood实际上,...Net中的所有文件处理系统都完全接受并解决了“垃圾”(包括其中的路径)问题。如果它困扰您,请执行absolute = Path.GetFullPath(absolute)它。
Nyerguds

16

这适用于不同驱动器上的路径,驱动器相对路径和实际相对路径。哎呀,如果basePath实际上不是绝对的,它甚至可以工作。它始终使用当前工作目录作为最终后备。

public static String GetAbsolutePath(String path)
{
    return GetAbsolutePath(null, path);
}

public static String GetAbsolutePath(String basePath, String path)
{
    if (path == null)
        return null;
    if (basePath == null)
        basePath = Path.GetFullPath("."); // quick way of getting current working directory
    else
        basePath = GetAbsolutePath(null, basePath); // to be REALLY sure ;)
    String finalPath;
    // specific for windows paths starting on \ - they need the drive added to them.
    // I constructed this piece like this for possible Mono support.
    if (!Path.IsPathRooted(path) || "\\".Equals(Path.GetPathRoot(path)))
    {
        if (path.StartsWith(Path.DirectorySeparatorChar.ToString()))
            finalPath = Path.Combine(Path.GetPathRoot(basePath), path.TrimStart(Path.DirectorySeparatorChar));
        else
            finalPath = Path.Combine(basePath, path);
    }
    else
        finalPath = path;
    // resolves any internal "..\" to get the true full path.
    return Path.GetFullPath(finalPath);
}

1
很好的解决方案,因为它根据基本路径组合了绝对路径或相对路径。我认为,relativePath参数应重命名为AbsoluteOrRelativePath,因为它实际上是它的代表。谢谢
Julio Nobre

1
好吧,如果它已经是一条绝对路径了,那只是一个特例,真的……该功能仍然旨在解决相对路径,哈哈。我只是在这里命名,以表明是哪个参数;)
Nyerguds

1
@JulioNobre,尤其是因为与相比,此处的args反转了Path.Combine。这很容易解决,但是我避免使用它,因为我经常使用它来解析工作目录上的相对路径,并且由于第一个arg看起来很奇怪而给了null。
Nyerguds

1
我很感谢您的建议,但仅在需要将基本路径与可能相对于该基本路径或绝对路径的另一路径组合时才打算使用此帮助程序。这就是为什么我更喜欢采用以下签名:GetAbsolutePath(String BasePath,String RelativeOrAbsolutePath)。如果某些参数为null,则会引发一个异常以强化两者都必须使用此方法。再次感谢:-)
Julio Nobre

2
是的,这很明智。可以编辑它只是为了弄乱一些参数。
Nyerguds

2

这是一个较旧的主题,但对某人可能有用。我已经解决了类似的问题,但就我而言,该路径不是文本的开头。

所以这是我的解决方案:

public static class StringExtension
{
    private const string parentSymbol = "..\\";
    private const string absoluteSymbol = ".\\";
    public static String AbsolutePath(this string relativePath)
    {
        string replacePath = AppDomain.CurrentDomain.BaseDirectory;
        int parentStart = relativePath.IndexOf(parentSymbol);
        int absoluteStart = relativePath.IndexOf(absoluteSymbol);
        if (parentStart >= 0)
        {
            int parentLength = 0;
            while (relativePath.Substring(parentStart + parentLength).Contains(parentSymbol))
            {
                replacePath = new DirectoryInfo(replacePath).Parent.FullName;
                parentLength = parentLength + parentSymbol.Length;
            };
            relativePath = relativePath.Replace(relativePath.Substring(parentStart, parentLength), string.Format("{0}\\", replacePath));
        }
        else if (absoluteStart >= 0)
        {
            relativePath = relativePath.Replace(".\\", replacePath);
        }
        return relativePath;
    }
}

例:

Data Source=.\Data\Data.sdf;Persist Security Info=False;
Data Source=..\..\bin\Debug\Data\Data.sdf;Persist Security Info=False;

1
嗯 您正在重新发明轮子。Path.GetFullPath自动解析。\和.. \。另外,您AbsolutePath通常在将扩展函数添加到String类中……可能有点过大。
Nyerguds

1
我说的是Path.GetFullPath总是将基本目录视为应用程序AppDomain的当前目录。在这种情况下,Path.GetFullPath无法从其他目录返回完整路径。但是,以下算法考虑了这一点……我的意思是,您只需要添加另一个可选参数即可代替CurrentDomainDirectory。
塞缪尔
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.