Windows 응용 프로그램에서 상대 경로를 절대 경로로 변환하는 방법은 무엇입니까?


90

Windows 응용 프로그램에서 상대 경로를 절대 경로로 어떻게 변환합니까?

ASP.NET에서 server.MapPath ()를 사용할 수 있다는 것을 알고 있습니다. 그러나 Windows 응용 프로그램에서 무엇을 할 수 있습니까?

내 말은, 그것을 처리 할 수있는 .NET 내장 함수가 있다면 ...


2
현재 디렉터리, 즉 작업 디렉터리에 대한 상대 경로를 의미합니까, 아니면 .exe 위치에 대한 상대 경로를 의미합니까?
Tobias Hertkorn

2
두 종류의 상대 경로가 있습니다. "A \ B \ C"형식이며 특정 염기를 의미하지 않는 경우. 다른 하나는 ". \ A \ B"또는 ".. \ A \ B"형식입니다. 현재 작업 디렉토리에 상대적입니다.
MSalters 09.09.09

1
@Amit Dhall : 그건 그렇고, 도움이되는 답변을 수락하고 찬성하는 것은 좋은 일입니다.
Francis B.

답변:


183

시도해 보셨습니까?

string absolute = Path.GetFullPath(relative);

? 실행 파일이 포함 된 디렉토리가 아니라 프로세스의 현재 작업 디렉토리를 사용합니다. 그래도 도움이되지 않으면 질문을 명확히하십시오.


4
exe가 어디에 있는지가 아니라 어디에서 앱을 시작하는지에 달려 있지 않습니까? 당연히 그 질문은 실제로 명확하지 않습니다.
Tobias Hertkorn

1
당신이 말했듯이 질문은 명확하지 않습니다. GetFullPath는 현재 작업 디렉터리에서 확인됩니다. 이를 나타내도록 내 응답을 편집하겠습니다.
Jon Skeet

1
응용 프로그램이 Windows 탐색기를 통해 시작되면 현재 디렉터리와 실행중인 어셈블리 디렉터리가 동일한 것으로 보입니다 (적어도 다른 작업이 수행 될 때까지). 바로 가기가 완전히 다른 위치에있는 실행 파일에 대한 바로 가기를 사용하는 경우에도 마찬가지입니다.
H2ONaCl 2015 년

19

.exe에 상대적인 경로를 얻으려면 다음을 사용하십시오.

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

4
Path.Combine에주의하십시오. '상대'부분이 슬래시로 시작하면 생각한대로 작동하지 않을 수 있습니다.
Noon Silk

2
@silky : 음, 그렇다면 상대적이지 않습니까?
Tor Haugen

1
Path.Combine드라이브 상대 경로도 처리 할 수없는 것 같습니다 . 보이는 초기 경로를 무시합니다. 내 자신의 전체 솔루션을 게시하고 있습니다.
Nyerguds

3
이것은 상대 경로를 처리 할 수 ​​없습니다. 디렉토리와 파일 이름 만 허용합니다. 두 번째 인수가와 같은 것으로 시작 ..하면 쓰레기가 생성됩니다.
Jonathan Wood

1
@JonathanWood 사실, 그 "쓰레기"(그 안에 포함 ..된 경로 )는 .Net의 모든 파일 조작 시스템에 의해 완벽하게 수용되고 해결됩니다. 신경 쓰이는 경우 실행 absolute = Path.GetFullPath(absolute)하십시오.
Nyerguds

15

이것은 다른 드라이브의 경로, 드라이브 상대 경로 및 실제 상대 경로에 대해 작동합니다. 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 2016

1
귀하의 조언에 감사 드리지만, 기본 경로를 해당 기본 경로에 상대적이거나 절대적 일 수있는 다른 경로와 결합해야 할 때만이 도우미를 사용하려고합니다. 그래서 GetAbsolutePath (String BasePath, String RelativeOrAbsolutePath) 시그니처를 채택했습니다. 일부 인수가 null 인 경우 예외가 발생하여 둘 다이 메서드를 사용하는 데 필수임을 강화합니다. 다시 한 번 감사드립니다 :-)
Julio Nobre

2
그래, 그게 현명하다. 그래도 일부 인수를 저글링하기 위해 이것을 편집하는 것을 귀찮게 할 수는 없습니다.
Nyerguds 2016

1

조금 오래된 주제이지만 누군가에게 유용 할 수 있습니다. 비슷한 문제를 해결했지만 제 경우에는 경로가 텍스트 시작 부분에 있지 않았습니다.

그래서 여기 내 해결책이 있습니다.

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.