Як перетворити відносний шлях на абсолютний шлях у програмі Windows?


90

Як перетворити відносний шлях на абсолютний шлях у програмі Windows?

Я знаю, що ми можемо використовувати server.MapPath () в ASP.NET. Але що ми можемо зробити у програмі Windows?

Я маю на увазі, якщо є вбудована функція .NET, яка може це впоратись ...


2
Ви маєте на увазі відносний шлях до поточного каталогу, іншими словами, робочого каталогу, або відносно розташування .exe?
Тобіас Герткорн

2
Існує два типи відносних шляхів. Один із форм "A \ B \ C" і не передбачає певної бази. Інший має вигляд ". \ A \ B" або ".. \ A \ B"; вони відносно поточного робочого каталогу.
MSalters

1
@Amit Dhall: До речі, добре прийняти та підтримати відповіді, які допоможуть вам.
Френсіс Б.

Відповіді:


183

Ти намагався:

string absolute = Path.GetFullPath(relative);

? Зверніть увагу, що для цього буде використано поточний робочий каталог процесу, а не каталог, що містить виконуваний файл. Якщо це не допомогло, будь ласка, поясніть своє питання.


4
Чи це не залежить від того, звідки ви запускаєте програму, і не від того, де знаходиться exe? Звичайно, питання насправді незрозуміле з цього приводу.
Тобіас Герткорн

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

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, оскільки він є тим, що він насправді представляє. Подяка
Хуліо Нобре

1
Ну, якщо це вже абсолютний шлях, це лише окремий випадок, насправді ... функція все-таки призначена для вирішення відносних шляхів, ха-ха. Я просто назвав це тут, щоб було зрозуміло, який параметр є яким;)
Нергудс

1
@JulioNobre тим більше, що аргументи тут зворотні порівняно з Path.Combine. Це легко виправити, але я уникаю цього, оскільки часто використовую його для вирішення відносних шляхів у робочому каталозі, а надання null як перший аргумент виглядає дивним.
Nyerguds

1
Я ціную вашу пораду, але я маю намір використовувати цей помічник лише тоді, коли мені потрібно поєднати базовий шлях з іншим шляхом, який може бути або відносно цього базового шляху, або абсолютним. Ось чому я віддав перевагу прийняти такий підпис: GetAbsolutePath (String BasePath, String RelativeOrAbsolutePath). Якщо якийсь аргумент дорівнює нулю, піднімається виняток, щоб підсилити, що обидва обов’язкові для використання цього методу. Ще раз дякую :-)
Хуліо Нобре

2
Так, це розумно. Неможливо потурбуватись редагувати це, щоб просто жонглювати деякими аргументами.
Nyerguds,

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.
Самуель
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.