Получение пути к домашнему каталогу на C #?


101

Хорошо, я проверил Environment.SpecialFolder, но для этого там ничего нет.

Я хочу получить домашний каталог текущего пользователя на C #. (например, c:\documents and settings\userпод XP, c:\users\userпод Vista и /home/userпод Unix.)

Я знаю, что могу читать переменные среды, чтобы узнать это, но я хочу сделать это кроссплатформенным способом.

Есть ли способ сделать это с помощью .NET (желательно с помощью mscorlib)?

ОБНОВЛЕНИЕ : Хорошо, это код, который я использовал:

string homePath = (Environment.OSVersion.Platform == PlatformID.Unix || 
                   Environment.OSVersion.Platform == PlatformID.MacOSX)
    ? Environment.GetEnvironmentVariable("HOME")
    : Environment.ExpandEnvironmentVariables("%HOMEDRIVE%%HOMEPATH%");

2
БУМ. Самый быстрый пистолет на западе: P
— Boris Callens

Не знаю о вашей машине, но на моем компьютере с XP% HOMEDRIVE %% HOMEPATH% - это сетевой каталог, а не c: \ Documents and Settings \ user \ MSalters \
— MSalters

Честно говоря, я считаю эту проблему недостаточной реализацией .NET ... вы должны посмотреть документацию для CSIDLS ( msdn.microsoft.com/en-us/library/bb762494.aspx ), чтобы увидеть полный список что поддерживает Windows: на самом деле вы ищете CSIDL_PROFILE, который поддерживается в Windows, но не .NET по какой-то непостижимой причине.
— Мэтью Шарли

1
Думаю, в следующий раз тебе стоит выразить результат в ответе.
— Питер

PlatformID.MacOSX не является обязательным, PlatformID.Unix также возвращает true на MacOSX (или, по крайней мере, так было раньше).
— Стефан Штайгер

Ответы:


51

Environment.SpecialFolder.Personalна самом деле не возвращает домашнюю папку, а возвращает папку « Мои документы ». Самый безопасный способ получить домашнюю папку в Win32 - это прочитать %HOMEDRIVE%%HOMEPATH%. Чтение переменных среды на самом деле очень переносимо (в Unix и Windows), поэтому я не уверен, почему плакат не хотел этого делать.

Отредактировано для добавления: для кроссплатформенного (Windows / Unix) C # я бы читал $HOMEо Unix, OSX и %HOMEDRIVE%%HOMEPATH%Windows.


Я точно знаю, что HOMEDRIVE не существует на * nix, и обычно это просто HOME, а не HOMEPATH.
— Мэтью Шарли

Мэтью, ты прав. Я добавил пояснение к исходному комментарию.
— sigint

12
Вы не можете использовать% USERPROFILE% в Windows?
— Лукас Джонс,

1
$ HOME также работает с OS X. Насколько я понимаю, это все еще неправильный ответ, поскольку вы выполняете определение платформы ... но чтобы получить точные запрошенные значения, это то, что вам нужно сделать.
— Мэтью Шарли,

2
person-b,% USERPROFILE% и% HOMEDRIVE %% HOMEPATH% часто одинаковы на персональных компьютерах, но часто указывают на разные места в сетевых средах. Например, на работе мой ПРОФИЛЬ ПОЛЬЗОВАТЕЛЯ - C: \ Documents and Settings \ username, а домашний каталог - Z: \, который представляет собой сетевой диск, резервные копии которого регулярно создаются ИТ-специалистами.
— sigint

94
Environment.GetFolderPath(Environment.SpecialFolder.UserProfile)

Личное - это Мои документы (или Документы в win7 и выше).


8
Обратите внимание, что UserProfile является новым в .NET 4.0, если вы используете .NET 2.0 / 3.5, вам необходимо вручную вызвать Win32 API со значением 40 для UserProfile
— linquize

И «Мои документы» - это не то же самое, что домашний каталог, за исключением Windows 95, 98 и ME.
— Джон Ханна

1
Не забудьте использовать System.IO.Path.DirectorySeparatorChar для создания пути к файлу, чтобы он оставался переносимым.
— thomiel

4
Не используйте DirectorySeperatorChar вручную. Используйте Path.Combine.
— Джон Гитцен 08

15

Я считаю, что вы ищете:

System.Environment.GetFolderPath(System.Environment.SpecialFolder.Personal)

Для справки, он фактически содержится в mscorlib.


Это вернет папку «Мои документы».
— MiffTheFox

«Мои документы» - это самое близкое к домашнему каталогу Windows.
— MSalters

8
@MStallers Нет,% HOMEDRIVE %% HOMEPATH% есть.
— MiffTheFox

Не совсем ... но альтернативой является PInvoke, и OP запросил управляемое решение.
— Мэтью Шарли

7
Обратите внимание, что Environment.SpecialFolder.UserProfile доступен в .NET 4.0, что вам и нужно
— linquize

8

В DotNetCore 1.1 System.Environment.SpecialFolderне существует. Он может существовать в версии 2.0-beta. А пока для этого вы можете использовать следующее:

var envHome = RuntimeInformation.IsOSPlatform(OSPlatform.Windows) ? "HOMEPATH" : "HOME";
var home = Environment.GetEnvironmentVariable(envHome);`

System.Environment.SpecialFolder
— Пользуюсь

4

В итоге ответ - нет. В .NET не существует простого системного метода получения домашнего каталога, поэтому мы могли бы ожидать реализации как в .NET в Windows, так и в Mono.

Вам нужно будет выполнить обнаружение ОС и перейти к конкретному коду ОС.


1

Когда вы говорите о кроссплатформенности, какие еще ОС вам нужно поддерживать? Возможно, вам потребуется выполнить простое определение ОС, чтобы выбрать метод поиска домашнего каталога, если вы работаете в ОС, отличной от Windows.

Этот веб-сайт, кажется, дает возможность делать то, что вам нужно, в Windows.


Если вы не используете какую-то глупую реализацию Framework Environment.GetFolder () должен работать кроссплатформенно.
— R. Martinho Fernandes

2
Должен . Реализация MS этого не делает.
— R. Martinho Fernandes

1

Это может быть сделано с помощью GetEnvironmentVariableв System.IO:

public string GetUserHome() {
    var homeDrive = Environment.GetEnvironmentVariable("HOMEDRIVE");
    if (!string.IsNullOrWhiteSpace(homeDrive))
    {
        var homePath = Environment.GetEnvironmentVariable("HOMEPATH");
        if (!string.IsNullOrWhiteSpace(homePath))
        {            
            var fullHomePath = homeDrive + Path.DirectorySeparatorChar + homePath;
            return Path.Combine(fullHomePath, "myFolder");
        }
        else
        {
            throw new Exception("Environment variable error, there is no 'HOMEPATH'");
        }
    }
    else
    {
        throw new Exception("Environment variable error, there is no 'HOMEDRIVE'");
    }
}

Затем выдает под окнами: C:\\\\Users\\myusername\\myFolder

Обратите внимание, что если вы используете

var fullHomePath = Path.Combine(homeDrive.ToString(), homePath.ToString())

он терпит неудачу, потому что производит: \\Users\\myusername\\myFolder


Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.