132

Okay, I've checked Environment.SpecialFolder, but there's nothing in there for this.

I want to get the home directory of the current user in C#. (e.g. c:\documents and settings\user under XP, c:\users\user under Vista, and /home/user under Unix.)

I know I can read enviroment variables to find this out, but I want to do this in a cross-platform way.

Is there any way I can do this with .NET (preferably using mscorlib)?

UPDATE: Okay, this is the code I ended up using:

string homePath = (Environment.OSVersion.Platform == PlatformID.Unix || 
                   Environment.OSVersion.Platform == PlatformID.MacOSX)
    ? Environment.GetEnvironmentVariable("HOME")
    : Environment.ExpandEnvironmentVariables("%HOMEDRIVE%%HOMEPATH%");
Per Lundberg
  • 3,837
  • 1
  • 36
  • 46
MiffTheFox
  • 21,302
  • 14
  • 69
  • 94
  • Dunno about your machine, but on my XP box %HOMEDRIVE%%HOMEPATH% is a network directory, not c:\Documents and Settings\user\MSalters\ – MSalters Jul 17 '09 at 14:55
  • To be honest, I consider this exact problem to be an underimplementation of .NET... you should look at the documentation for CSIDLS (http://msdn.microsoft.com/en-us/library/bb762494.aspx) to see a full list of what Windows supports: What you are actually looking for is CSIDL_PROFILE, which is supported in Windows, but not by .NET for some unfathomable reason. – Matthew Scharley Jul 17 '09 at 15:01
  • 1
    I think you should put the result in an answer, next time. – Peteter May 07 '12 at 15:05
  • PlatformID.MacOSX is not necessary, PlatformID.Unix returns true on MacOSX, too (or at the very least it used to). – Stefan Steiger Sep 06 '15 at 21:26

9 Answers9

150

You are looking for Environment.SpecialFolder.UserProfile which refers to C:\Users\myname on Windows and /home/myname on Unix/Linux:

Environment.GetFolderPath(Environment.SpecialFolder.UserProfile)

Note that Environment.SpecialFolder.Personal is My Documents (or Documents in win7 and above), but same as home directory on Unix/Linux.

Sridhar Ratnakumar
  • 81,433
  • 63
  • 146
  • 187
James
  • 1,509
  • 2
  • 9
  • 2
59

Environment.SpecialFolder.Personal doesn't actually return the home folder, it returns the My Documents folder. The safest way to get the home folder on Win32 is to read %HOMEDRIVE%%HOMEPATH%. Reading environment variables is actually very portable to do (across Unix and Windows), so I'm not sure why the poster wanted to not do it.

Edited to add: For crossplatform (Windows/Unix) C#, I'd read $HOME on Unix and OSX and %HOMEDRIVE%%HOMEPATH% on Windows.

StackzOfZtuff
  • 2,534
  • 1
  • 28
  • 25
sigint
  • 1,842
  • 1
  • 22
  • 27
  • I know for a fact HOMEDRIVE doesn't exist on *nix, and normally it's just HOME, not HOMEPATH. – Matthew Scharley Jul 17 '09 at 14:50
  • Matthew, you're right. I added a clarification on the original comment. – sigint Jul 17 '09 at 14:51
  • 14
    Can you not use %USERPROFILE% on Windows? – Lucas Jones Jul 17 '09 at 14:53
  • Mac OSX *is* UNIX, officially. It also works on Linux, which is similar enough to UNIX. – MSalters Jul 17 '09 at 14:53
  • 1
    $HOME works on OS X too. This still isn't the correct answer as far as I'm concerned though since you're doing platform detection... but to get at the exact values asked for, that's about what you have to do. – Matthew Scharley Jul 17 '09 at 14:54
  • Actually, OS X is BSD, but that's a distinction for the anals of some history book or another... – Matthew Scharley Jul 17 '09 at 14:55
  • Thank you, I posted the code I ended up using to the original question. – MiffTheFox Jul 17 '09 at 14:58
  • 3
    person-b, %USERPROFILE% and %HOMEDRIVE%%HOMEPATH% are often the same on personal PCs, but often point to different places in networked environments. E.g., at work my USERPROFILE is C:\Documents and Settings\username but home directory is Z:\, which is a networked drive which is backed up by IT regularly. – sigint Jul 17 '09 at 15:04
  • I have exactly the same setup at my work environment as sigint. – Tahir Hassan Mar 24 '17 at 20:56
16

I believe what you are looking for is:

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

For reference, it is infact contained in mscorlib.

Matthew Scharley
  • 127,823
  • 52
  • 194
  • 222
8

In DotNetCore 1.1 System.Environment.SpecialFolder does not exist. It might exist in 2.0-beta. Until then, to do this you can use the following:

var envHome = RuntimeInformation.IsOSPlatform(OSPlatform.Windows) ? "HOMEPATH" : "HOME";
var home = Environment.GetEnvironmentVariable(envHome);`
abatishchev
  • 98,240
  • 88
  • 296
  • 433
KBP
  • 1,500
  • 2
  • 14
  • 14
4

The bottom line answer is No. The is no simple System based method in .NET to get the Home directory such that we could expect an implementation in both .NET on Windows and in Mono.

You will need to do some OS detection and branch to OS specific code.

AnthonyWJones
  • 187,081
  • 35
  • 232
  • 306
2

This can be done using GetEnvironmentVariable in 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'");
    }
}

Then it produces under windows: C:\\\\Users\\myusername\\myFolder

Note that if you use

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

it fails because it produces: \\Users\\myusername\\myFolder

Ehsan Iran-Nejad
  • 1,697
  • 1
  • 15
  • 20
Nicosmik
  • 791
  • 1
  • 5
  • 7
1

When you say cross-platform way, what other OSs do you need to support? You may need to do some simple OS detection to select the method for finding the home directory if you're running on a non-Windows OS.

This website seems to give a way to do what you need in Windows.

John D.
  • 324
  • 1
  • 6
1

Just for future reference, the list of pre-defined variables in Windows 10, taken from Windows 10 default environment variables.

VARIABLE WINDOWS 10
%ALLUSERSPROFILE% C:\ProgramData
%APPDATA% C:\Users{username}\AppData\Roaming
%CD% Current directory full path.
(cmd only)
%CMDCMDLINE% Returns exact command line used to start current cmd.exe session.
(cmd only)
%CMDEXTVERSION% Number of current command processor extensions.
(cmd only)
%CommonProgramFiles% C:\Program Files\Common Files
%CommonProgramFiles(x86)% C:\Program Files (x86)\Common Files
%CommonProgramW6432% C:\Program Files\Common Files
%COMPUTERNAME% The computer name of the current local system.
%COMSPEC% C:\Windows\System32\cmd.exe
%DATE% Current date in format determined by Date command.
(cmd only)
%ERRORLEVEL% Number defining exit status of previous command or program.
(cmd only)
%HOMEDRIVE% C:|
%HOMEPATH% C:\Users{username}
%LOCALAPPDATA% C:\Users{username}\AppData\Local
%LOGONSERVER% \{domain_logon_server}
\MicrosoftAccount
%NUMBER_OF_PROCESSORS% 8
%OS% Windows_NT
%PATH% C:\Windows;
C:\Windows\System32;
C:\Windows\System32\Wbem;
C:\Windows\System32\WindowsPowerShell\v1.0
%PathExt% .COM;.EXE;.BAT;.CMD;.VBS;.VBE;.JS;.JSE;.WSF;.WSH;.MSC
%PROCESSOR_ARCHITECTURE% AMD64
%PROCESSOR_IDENTIFIER% Intel64 Family 6 Model 158 Stepping 9, GenuineIntel
%PROCESSOR_LEVEL% 6
%PROCESSOR_REVISION% 9e09
%PROGRAMDATA% C:\ProgramData
%PROGRAMFILES% C:\Program Files
%ProgramW6432% C:\Program Files
%PROGRAMFILES(X86)% C:\Program Files (x86)
%PROMPT% Code for current command prompt format.
Code is usually $P$G
(cmd only)
%PSModulePath% C:\Windows\system32\WindowsPowerShell\v1.0\Modules|
%PUBLIC% C:\Users\Public
%RANDOM% To get random number between 0 and 32767.
(cmd only)
%SessionName% When logging on directly to machine, returns "Console".
When client connects via terminal server session, is combination
of connection name, followed by pound symbol {#} and session number.
%SystemDrive% C:
%SystemRoot% C:\Windows
%TEMP% C:\Users{username}\AppData\Local\Temp
%TMP% C:\Users{username}\AppData\Local\Temp
%TIME% Current time in format determined by Time command.
(cmd only)
%USERDOMAIN% The network domain name associated with the current user.
%USERDOMAIN_ROAMINGPROFILE% The network domain name associated with the current roaming profile.
%USERNAME% {username}
%USERPROFILE% C:\Users{username}
%WINDIR% C:\Windows
Xan-Kun Clark-Davis
  • 2,664
  • 2
  • 27
  • 38
0

I don't have a machine to test it on, but %HOMESHARE% might work for you. Otherwise, here's a pretty good list of environment variables.

JP Alioto
  • 44,864
  • 6
  • 88
  • 112