Windowsアプリケーションで相対パスを絶対パスに変換する方法は?


89

Windowsアプリケーションで相対パスを絶対パスに変換するにはどうすればよいですか?

ASP.NETでserver.MapPath()を使用できることはわかっています。しかし、Windowsアプリケーションで何ができるでしょうか。

つまり、それを処理できる.NET組み込み関数がある場合...


2
現在のディレクトリへの相対パス、つまり作業ディレクトリ、または.exeの場所への相対パスですか?
Tobias Hertkorn

2
相対パスには2種類あります。「A \ B \ C」の形式の場合、特定のベースを意味するものではありません。もう1つは "。\ A \ B"または ".. \ A \ B"という形式です。これらは、現在の作業ディレクトリを基準にしています。
MSalters 2009

1
@Amit Dhall:ちなみに、あなたを助ける答えを受け入れて賛成することは良いことです。
フランシスB.

回答:


180

やってみました:

string absolute = Path.GetFullPath(relative);

?これは、実行可能ファイルを含むディレクトリではなく、プロセスの現在の作業ディレクトリを使用することに注意してください。それでも問題が解決しない場合は、質問を明確にしてください。


3
それはあなたがアプリをどこから起動するかに依存しませんか、exeがどこにあるかに依存しませんか?確かにその質問は本当に明確ではありません。
Tobias Hertkorn 2009

1
あなたが言うように、質問は明確ではありません。GetFullPathは、現在の作業ディレクトリから解決されます。これを示すために応答を編集します。
Jon Skeet

1
Windowsエクスプローラーを介してアプリケーションを起動した場合、現在のディレクトリと実行中のアセンブリディレクトリは同じであるように見えます(少なくとも何かを行うために何かが行われるまで)。これは、ショートカットが完全に異なる場所にある実行可能ファイルへのショートカットを使用する場合にも当てはまります。
H2ONaCl 2015年

19

.exeからの相対パスを取得したい場合は、

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

4
Path.Combineに注意してください。「相対」部分がスラッシュで始まる場合、それはあなたが思っていることをしないかもしれません。
正午シルク

2
@シルキー:まあ、それは相対的ではないでしょうか?
Tor Haugen

1
思わPath.Combineでもドライブ相対パスを処理することはできません。思われる初期パスを無視するだけです。私は自分の完全なソリューションを投稿しています。
Nyerguds、2016

3
これは相対パスを処理できません。ディレクトリとファイル名のみを受け入れます。2番目の引数がで始まる場合、..ゴミが発生します。
ジョナサンウッド

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 2016年

1
まあ、それがすでに絶対パスであるなら、それは単なる特別なケースです、本当に...関数はまだ相対パスを解決することを意図しています、笑。ここでは、どのパラメーターがどのパラメーターであるかを明確にするために、その名前を付けました;)
Nyerguds

1
@JulioNobreは、特にここでの引数がと比較して逆になっているためPath.Combineです。これは簡単に修正できますが、作業ディレクトリの相対パスを解決するために頻繁に使用し、最初の引数としてnullを指定すると奇妙に見えるため、回避します。
Nyerguds

1
私はあなたの助言に感謝しますが、私がこのヘルパーを使用するのは、ベースパスを、そのベースパスに対する相対パスまたは絶対パスである別のパスと組み合わせる必要がある場合のみです。そのため、次のシグネチャを採用することにしました:GetAbsolutePath(String BasePath、String RelativeOrAbsolutePath)。一部の引数がnullの場合、例外が発生して、このメソッドを使用するために両方が必須であることを強化します。繰り返しますが、ありがとうございました:-)
Julio Nobre 2016年

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の代わりになる別のオプションパラメータを追加する必要があるだけです。
Samuel
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.