Pobieranie ścieżki katalogu domowego w C #?


101

OK, sprawdziłem Environment.SpecialFolder, ale nie ma tam nic do tego.

Chcę uzyskać katalog domowy bieżącego użytkownika w C #. (np. c:\documents and settings\userpod XP, c:\users\userVista i /home/userUnix.)

Wiem, że potrafię czytać zmienne środowiskowe, aby się tego dowiedzieć, ale chcę to zrobić w sposób wieloplatformowy.

Czy jest jakiś sposób, żebym mógł to zrobić z .NET (najlepiej używając mscorlib)?

AKTUALIZACJA : OK, to jest kod, którego użyłem:

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

2
BUM. Najszybsze działo na zachodzie: P
Boris Callens

Nie wiem o twoim komputerze, ale na mojej skrzynce XP% HOMEDRIVE %% HOMEPATH% to katalog sieciowy, a nie c: \ Documents and Settings \ user \ MSalters \
MSalters

Szczerze mówiąc uważam, że ten właśnie problem jest niedostateczną implementacją .NET ... powinieneś zajrzeć do dokumentacji CSIDLS ( msdn.microsoft.com/en-us/library/bb762494.aspx ), aby zobaczyć pełną listę co obsługuje system Windows: W rzeczywistości szukasz CSIDL_PROFILE, który jest obsługiwany w systemie Windows, ale nie przez .NET z jakiegoś niezrozumiałego powodu.
Matthew Scharley,

1
Myślę, że następnym razem powinieneś umieścić wynik w odpowiedzi.
Peteter

PlatformID.MacOSX nie jest konieczny, PlatformID.Unix zwraca również wartość true na MacOSX (a przynajmniej tak było).
Stefan Steiger

Odpowiedzi:


51

Environment.SpecialFolder.Personalw rzeczywistości nie zwraca folderu domowego, zwraca folder Moje dokumenty . Najbezpieczniejszym sposobem uzyskania folderu domowego na Win32 jest przeczytanie %HOMEDRIVE%%HOMEPATH%. Odczytywanie zmiennych środowiskowych jest w rzeczywistości bardzo przenośne (w systemach Unix i Windows), więc nie jestem pewien, dlaczego autor chciał tego nie robić.

Edytowano w celu dodania: W przypadku wieloplatformowego (Windows / Unix) C # czytałem $HOMEw systemach Unix i OSX oraz %HOMEDRIVE%%HOMEPATH%Windows.


Wiem na pewno, że HOMEDRIVE nie istnieje na * nix i zwykle jest to po prostu DOM, a nie HOMEPATH.
Matthew Scharley,

Matthew, masz rację. Dodałem wyjaśnienie do pierwotnego komentarza.
sigint

12
Czy nie możesz używać% USERPROFILE% w systemie Windows?
Lucas Jones,

1
$ HOME działa również na OS X. To wciąż nie jest prawidłowa odpowiedź, jeśli o mnie chodzi, ponieważ robisz wykrywanie platformy ... ale aby uzyskać dokładne wartości, o które proszono, to właśnie musisz zrobić.
Matthew Scharley,

2
person-b,% USERPROFILE% i% HOMEDRIVE %% HOMEPATH% są często takie same na komputerach osobistych, ale często wskazują różne miejsca w środowiskach sieciowych. Np. W pracy mój USERPROFILE to C: \ Documents and Settings \ nazwa użytkownika, ale katalog domowy to Z: \, który jest dyskiem sieciowym, którego kopie zapasowe są regularnie tworzone przez dział IT.
sigint

93
Environment.GetFolderPath(Environment.SpecialFolder.UserProfile)

Osobiste to Moje Dokumenty (lub Dokumenty w systemach Windows 7 i nowszych).


8
Zauważ, że UserProfile jest nowością w .NET 4.0, jeśli używasz .NET 2.0 / 3.5, musisz ręcznie wywołać Win32 API z wartością 40 dla
UserProfile

A „Moje dokumenty” to nie to samo, co katalog domowy, z wyjątkiem Windows 95, 98 i ME.
Jon Hanna

1
Nie zapomnij użyć System.IO.Path.DirectorySeparatorChar do zbudowania ścieżki do pliku, aby była przenośna.
thomiel

4
Nie używaj DirectorySeperatorChar ręcznie. Użyj Path.Combine.
John Gietzen

14

Wierzę, że szukasz:

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

Dla porównania, jest to faktycznie zawarte w mscorlib.


To zwraca folder Moje dokumenty.
MiffTheFox,

„Moje dokumenty” to najbliższa rzecz, jaką Windows ma do katalogu domowego.
MSalters

8
@MStallers Nie,% HOMEDRIVE %% HOMEPATH% jest.
MiffTheFox,

Niezupełnie ... ale alternatywą jest PInvoke, a OP poprosił o rozwiązanie zarządzane.
Matthew Scharley,

7
Zwróć uwagę, że Environment.SpecialFolder.UserProfile jest dostępny w .NET 4.0, co jest tym, czego potrzebujesz
linquize

8

W DotNetCore 1,1 System.Environment.SpecialFoldernie istnieje. Może istnieć w wersji 2.0-beta. Do tego czasu możesz skorzystać z:

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

Używam 2.0 i System.Environment.SpecialFolderistnieje
snotyak

4

Ostateczna odpowiedź brzmi: nie. Nie ma prostej metody opartej na systemie w .NET, aby uzyskać katalog domowy, tak że moglibyśmy oczekiwać implementacji zarówno w .NET w systemie Windows, jak iw Mono.

Będziesz musiał wykonać pewne wykrywanie systemu operacyjnego i przejść do kodu specyficznego dla systemu operacyjnego.


1

Kiedy mówisz o sposobie międzyplatformowym, jakie inne systemy operacyjne potrzebujesz obsługi? Może być konieczne wykonanie prostego wykrywania systemu operacyjnego, aby wybrać metodę znajdowania katalogu domowego, jeśli używasz systemu operacyjnego innego niż Windows.

Wydaje się, że ta witryna umożliwia robienie tego, czego potrzebujesz w systemie Windows.


Chyba że używasz jakiejś implementacji braindead środowiska Framework Environment. GetFolder () powinien działać na wielu platformach.
R. Martinho Fernandes

2
Powinienem . Implementacja MS tego nie robi.
R. Martinho Fernandes

1

Można to zrobić przy użyciu GetEnvironmentVariablew 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'");
    }
}

Następnie produkuje pod oknami: C:\\\\Users\\myusername\\myFolder

Zwróć uwagę, że jeśli używasz

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

zawodzi, ponieważ wytwarza: \\Users\\myusername\\myFolder


Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.