Bir Windows uygulamasında göreli bir yolu mutlak bir yola nasıl dönüştürebilirim?


92

Bir Windows uygulamasında göreli yolu mutlak yola nasıl dönüştürebilirim?

ASP.NET'te server.MapPath () kullanabileceğimizi biliyorum. Ama bir Windows uygulamasında ne yapabiliriz?

Demek istediğim, eğer bunu halledebilecek bir .NET yerleşik işlevi varsa ...


2
Geçerli dizine, başka bir deyişle çalışma dizinine veya .exe'nin konumuna göre göreli bir yolu mu kastediyorsunuz?
Tobias Hertkorn

2
İki tür göreceli yol vardır. Biri "A \ B \ C" şeklindedir ve belirli bir tabanı ima etmez. Diğeri ". \ A \ B" veya ".. \ A \ B" biçimindedir; bunlar geçerli çalışma dizinine göredir.
MSalters

1
@Amit Dhall: Bu arada, size yardımcı olan cevapları kabul etmek ve onlara destek vermek iyi bir şey.
Francis B.

Yanıtlar:


184

Denedin mi:

string absolute = Path.GetFullPath(relative);

? Bunun, yürütülebilir dosyayı içeren dizini değil, işlemin geçerli çalışma dizinini kullanacağını unutmayın. Bu yardımcı olmazsa, lütfen sorunuzu netleştirin.


4
Bu, exe'nin bulunduğu yere bağlı değil, uygulamayı nereden başlattığınıza bağlı olmaz mı? Kabul edilen soru bu konuda gerçekten net değil.
Tobias Hertkorn

1
Dediğiniz gibi, soru net değil. GetFullPath, geçerli çalışma dizininden çözülür. Bunu belirtmek için yanıtımı düzenleyeceğim.
Jon Skeet

1
Bir uygulama Windows Gezgini aracılığıyla başlatılırsa, geçerli dizin ve yürütme derleme dizini aynı görünür (en azından onları farklı kılmak için bir şeyler yapılana kadar). Bu, kısayolun tamamen farklı bir yerde bulunduğu yürütülebilir dosyaya bir kısa yol kullansanız bile geçerlidir.
H2ONaCl

19

.Exe ile göreli yolu elde etmek istiyorsanız şunu kullanın:

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

4
Path.Combine konusunda dikkatli olun. 'Göreli' kısım eğik çizgiyle başlıyorsa, yapacağını düşündüğünüz şeyi yapmayabilir.
Noon Silk

2
@silky: o zaman göreceli değil, değil mi?
Tor Haugen

1
Görünüşe Path.Combinegöre sürücüye bağlı yolları bile idare edemiyor. Göründüğü ilk yolu görmezden geliyor. Kendi tam çözümümü gönderiyorum.
Nyerguds

3
Bu göreceli bir yolu idare edemez. Yalnızca bir dizin ve dosya adını kabul eder. İkinci argüman ..buna benzer bir şeyle başlarsa , çöp üretecektir.
Jonathan Wood

1
@JonathanWood Aslında, bu "çöp" ( ..bunlara dahil olan yollar ) .Net'teki tüm dosya işleme sistemleri tarafından mükemmel bir şekilde kabul edilir ve çözülür. Sizi rahatsız ediyorsa, absolute = Path.GetFullPath(absolute)uygulayın.
Nyerguds

15

Bu, farklı sürücülerdeki yollar, sürücüye bağlı yollar ve gerçek göreceli yollar için çalışır. Heck, basePathaslında mutlak değilse bile çalışır ; her zaman son geri dönüş olarak mevcut çalışma dizinini kullanır.

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
Mutlak veya akraba yolu bir temel yola göre birleştirdiği için harika bir çözüm. Bence, relatifPath bağımsız değişkeni, gerçekten temsil ettiği için, AbsoluteOrRelativePath olarak yeniden adlandırılmalıdır. Teşekkürler
Julio Nobre

1
Zaten mutlak bir yol ise, bu sadece özel bir durum, gerçekten ... işlev hala göreceli yolları çözmeyi amaçlıyor, lol. Hangi parametrenin hangisi olduğunu netleştirmek için buraya adını verdim;)
Nyerguds

1
@JulioNobre özellikle buradaki argümanlar ile karşılaştırıldığında tersine çevrildiği için Path.Combine. Bu kolayca düzeltilebilir, ancak çalışma dizinindeki göreli yolları çözmek için sıklıkla kullandığım ve ilk argüman garip göründüğü için boş değer verdiğim için bundan kaçınıyorum.
Nyerguds

1
Tavsiyenizi takdir ediyorum, ancak bu yardımcıyı yalnızca bir temel yolu, o temel yola göreceli veya mutlak olabilecek başka bir yolla birleştirmem gerektiğinde kullanmaya niyetliyim. Bu yüzden aşağıdaki imzayı benimsemeyi tercih ettim: GetAbsolutePath (String BasePath, String RelativeOrAbsolutePath). Bazı argümanlar boşsa, bu yöntemi kullanmak için her ikisinin de zorunlu olduğunu pekiştirmek için bir istisna oluşturulur. Tekrar teşekkürler :-)
Julio Nobre

2
Evet, bu mantıklı. Yine de bazı değiştirgeleri karıştırmak için bunu düzenlemekle uğraşmayın.
Nyerguds

1

Biraz daha eski bir konu ama birisi için faydalı olabilir. Benzer bir sorunu çözdüm, ancak benim durumumda yol, metnin başında değildi.

İşte benim çözümüm:

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;
    }
}

Misal:

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

1
Um. Tekerleği yeniden icat ediyorsunuz. Path.GetFullPathçözer. \ ve .. \ otomatik olarak. Ayrıca, AbsolutePathgenel olarak String sınıfına uzantı işlevini ekliyorsunuz ... biraz fazla olabilir.
Nyerguds

1
Path.GetFullPath'in her zaman temel dizini uygulamanın AppDomain'inin geçerli dizini olarak gördüğünü söylemekte hatalı mıyım? Bu durumda, Path.GetFullPath farklı bir dizinden tam yolu döndüremez. Ancak aşağıdaki algoritma bunu dikkate alıyor ... Yani, sadece CurrentDomainDirectory'nin yerini alacak başka bir isteğe bağlı parametre eklemeniz gerekiyor.
Samuel
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.