Mendapatkan jalur direktori home di C #?

101

Oke, saya sudah memeriksa Environment.SpecialFolder, tapi tidak ada apa-apa di sana untuk ini.

Saya ingin mendapatkan direktori home dari pengguna saat ini di C #. (mis. di c:\documents and settings\userbawah XP, di c:\users\userbawah Vista, dan di /home/userbawah Unix.)

Saya tahu saya dapat membaca variabel lingkungan untuk mengetahui hal ini, tetapi saya ingin melakukan ini dengan cara lintas platform.

Apakah ada cara agar saya dapat melakukan ini dengan .NET (sebaiknya menggunakan mscorlib)?

UPDATE : Oke, ini adalah kode yang akhirnya saya gunakan:

string homePath = (Environment.OSVersion.Platform == PlatformID.Unix || 
                   Environment.OSVersion.Platform == PlatformID.MacOSX)
    ? Environment.GetEnvironmentVariable("HOME")
    : Environment.ExpandEnvironmentVariables("%HOMEDRIVE%%HOMEPATH%");
MiffTheFox
sumber
2
LEDAKAN. Senjata tercepat di barat: P
Boris Callens
Tidak tahu tentang mesin Anda, tetapi di kotak XP saya% HOMEDRIVE %% HOMEPATH% adalah direktori jaringan, bukan c: \ Documents and Settings \ user \ MSalters \
MSalters
Sejujurnya, saya menganggap masalah ini sebagai underimplementation NET ... Anda harus melihat dokumentasi untuk CSIDLS ( msdn.microsoft.com/en-us/library/bb762494.aspx ) untuk melihat daftar lengkap apa yang didukung Windows: Apa yang sebenarnya Anda cari adalah CSIDL_PROFILE, yang didukung di Windows, tetapi bukan oleh .NET karena alasan yang tidak terduga.
Matthew Scharley
1
Saya pikir Anda harus meletakkan hasilnya di jawaban, lain kali.
Peteter
PlatformID.MacOSX tidak diperlukan, PlatformID.Unix juga mengembalikan nilai true di MacOSX (atau setidaknya dulu).
Stefan Steiger

Jawaban:

51

Environment.SpecialFolder.Personaltidak benar-benar mengembalikan folder utama, ini mengembalikan folder Dokumen Saya . Cara paling aman untuk mendapatkan folder home di Win32 adalah dengan membaca %HOMEDRIVE%%HOMEPATH%. Membaca variabel lingkungan sebenarnya sangat portabel untuk melakukan (di Unix dan Windows), jadi saya tidak yakin mengapa poster ingin tidak melakukannya.

Diedit untuk menambahkan: Untuk lintas platform (Windows / Unix) C #, saya akan membaca $HOMEtentang Unix dan OSX dan %HOMEDRIVE%%HOMEPATH%Windows.

sigint
sumber
Saya tahu pasti HOMEDRIVE tidak ada di * nix, dan biasanya hanya HOME, bukan HOMEPATH.
Matthew Scharley
Matthew, kamu benar. Saya menambahkan klarifikasi pada komentar asli.
sigint
12
Bisakah Anda tidak menggunakan% USERPROFILE% di Windows?
Lucas Jones
1
$ HOME juga berfungsi di OS X. Ini masih bukan jawaban yang benar sejauh yang saya ketahui karena Anda melakukan deteksi platform ... tetapi untuk mendapatkan nilai pasti yang diminta, itulah yang harus Anda lakukan.
Matthew Scharley
2
person-b,% USERPROFILE% dan% HOMEDRIVE %% HOMEPATH% sering kali sama pada PC pribadi, tetapi sering menunjuk ke tempat yang berbeda di lingkungan jaringan. Misalnya, di tempat kerja USERPROFILE saya adalah C: \ Documents and Settings \ username tetapi direktori home adalah Z: \, yang merupakan drive jaringan yang dicadangkan oleh IT secara teratur.
sigint
92
Environment.GetFolderPath(Environment.SpecialFolder.UserProfile)

Personal is My Documents (atau Dokumen di win7 dan di atasnya).

James
sumber
8
Perhatikan bahwa UserProfile baru di .NET 4.0, jika Anda menggunakan .NET 2.0 / 3.5, Anda harus memanggil win32 API secara manual dengan nilai 40 untuk UserProfile
linquize
Dan "My Documents" tidak sama dengan direktori home, kecuali di Windows 95, 98 dan ME.
Jon Hanna
1
Jangan lupa untuk menggunakan System.IO.Path.DirectorySeparatorChar untuk membangun jalur file Anda agar tetap portabel.
thomiel
4
Jangan gunakan DirectorySeperatorChar secara manual. Gunakan Path.Combine.
John Gietzen
14

Saya yakin apa yang Anda cari adalah:

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

Untuk referensi, itu sebenarnya terkandung dalam mscorlib.

Matthew Scharley
sumber
Itu mengembalikan folder Dokumen Saya.
MiffTheFox
"My Documents" adalah hal terdekat yang dimiliki Windows ke direktori home.
MSalters
8
@MStallers Tidak,% HOMEDRIVE %% HOMEPATH% adalah.
MiffTheFox
Tidak cukup ... tetapi alternatifnya adalah PInvoke, dan OP meminta solusi terkelola.
Matthew Scharley
7
Perhatikan bahwa Environment.SpecialFolder.UserProfile tersedia dalam .NET 4.0, yang Anda inginkan
linquize
8

Di DotNetCore 1.1 System.Environment.SpecialFoldertidak ada. Mungkin ada di 2.0-beta. Sampai saat itu, untuk melakukan ini, Anda dapat menggunakan yang berikut ini:

var envHome = RuntimeInformation.IsOSPlatform(OSPlatform.Windows) ? "HOMEPATH" : "HOME";
var home = Environment.GetEnvironmentVariable(envHome);`
KBP
sumber
Saya menggunakan 2.0 dan System.Environment.SpecialFolderada
snotyak
4

Jawaban intinya adalah Tidak. Tidak ada metode berbasis Sistem sederhana di .NET untuk mendapatkan direktori Home sehingga kita dapat mengharapkan implementasi di .NET di Windows dan di Mono.

Anda perlu melakukan beberapa deteksi OS dan bercabang ke kode khusus OS.

AnthonyWJones
sumber
1

Ketika Anda mengatakan cara lintas platform, OS lain apa yang perlu Anda dukung? Anda mungkin perlu melakukan beberapa deteksi OS sederhana untuk memilih metode untuk menemukan direktori home jika Anda menjalankan OS non-Windows.

Situs web ini tampaknya memberikan cara untuk melakukan apa yang Anda butuhkan di Windows.

John D.
sumber
Kecuali Anda menggunakan beberapa implementasi braindead dari Framework Environment. GetFolder () harus bekerja lintas platform.
R. Martinho Fernandes
2
Seharusnya . Implementasi MS tidak melakukannya.
R. Martinho Fernandes
1

Hal ini dapat dilakukan dengan menggunakan GetEnvironmentVariabledi 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'");
    }
}

Kemudian menghasilkan di bawah jendela: C:\\\\Users\\myusername\\myFolder

Perhatikan bahwa jika Anda menggunakan

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

gagal karena menghasilkan: \\Users\\myusername\\myFolder

Nicosmik
sumber
0

Saya tidak memiliki mesin untuk mengujinya, tetapi %HOMESHARE%mungkin berhasil untuk Anda. Jika tidak, berikut daftar variabel lingkungan yang cukup bagus .

JP Alioto
sumber