¿Obteniendo la ruta del directorio de inicio en C #?

101

Bien, he comprobado Environment.SpecialFolder, pero no hay nada allí para esto.

Quiero obtener el directorio de inicio del usuario actual en C #. (por ejemplo, c:\documents and settings\userbajo XP, c:\users\userVista y /home/userUnix).

Sé que puedo leer variables ambientales para averiguarlo, pero quiero hacerlo de forma multiplataforma.

¿Hay alguna forma de que pueda hacer esto con .NET (preferiblemente usando mscorlib)?

ACTUALIZACIÓN : Bien, este es el código que terminé usando:

string homePath = (Environment.OSVersion.Platform == PlatformID.Unix || 
                   Environment.OSVersion.Platform == PlatformID.MacOSX)
    ? Environment.GetEnvironmentVariable("HOME")
    : Environment.ExpandEnvironmentVariables("%HOMEDRIVE%%HOMEPATH%");
MiffTheFox
fuente
2
AUGE. El arma más rápida del oeste: P
Boris Callens
No sé sobre su máquina, pero en mi caja XP% HOMEDRIVE %% HOMEPATH% es un directorio de red, no c: \ Documents and Settings \ user \ MSalters \
MSalters
Para ser honesto, considero que este problema exacto es una implementación insuficiente de .NET ... debería consultar la documentación de CSIDLS ( msdn.microsoft.com/en-us/library/bb762494.aspx ) para ver una lista completa de Qué admite Windows: Lo que en realidad está buscando es CSIDL_PROFILE, que es compatible con Windows, pero no con .NET por alguna razón insondable.
Matthew Scharley
1
Creo que debería poner el resultado en una respuesta, la próxima vez.
Peteter
PlatformID.MacOSX no es necesario, PlatformID.Unix también devuelve verdadero en MacOSX (o al menos solía hacerlo).
Stefan Steiger

Respuestas:

51

Environment.SpecialFolder.Personalen realidad no devuelve la carpeta de inicio, devuelve la carpeta Mis documentos . La forma más segura de obtener la carpeta de inicio en Win32 es leer %HOMEDRIVE%%HOMEPATH%. La lectura de las variables de entorno es en realidad muy portátil que hacer (a través de Unix y Windows), así que no estoy seguro de por qué el cartel quería no hacerlo.

Editado para agregar: Para multiplataforma (Windows / Unix) C #, leería $HOMEen Unix y OSX y %HOMEDRIVE%%HOMEPATH%en Windows.

sigint
fuente
Sé con certeza que HOMEDRIVE no existe en * nix, y normalmente es solo HOGAR, no HOMEPATH.
Matthew Scharley
Matthew, tienes razón. Agregué una aclaración sobre el comentario original.
sigint
12
¿No puede usar% USERPROFILE% en Windows?
Lucas Jones
1
$ HOME también funciona en OS X. Sin embargo, esta todavía no es la respuesta correcta en lo que a mí respecta, ya que está haciendo detección de plataforma ... pero para obtener los valores exactos solicitados, eso es lo que debe hacer.
Matthew Scharley
2
person-b,% USERPROFILE% y% HOMEDRIVE %% HOMEPATH% suelen ser iguales en PC personales, pero a menudo apuntan a diferentes lugares en entornos de red. Por ejemplo, en el trabajo, mi PERFIL DE USUARIO es C: \ Documentos y configuración \ nombre de usuario, pero el directorio de inicio es Z: \, que es una unidad en red que TI regularmente respalda.
sigint
92
Environment.GetFolderPath(Environment.SpecialFolder.UserProfile)

Personal es Mis documentos (o Documentos en win7 y superior).

James
fuente
8
Tenga en cuenta que UserProfile es nuevo en .NET 4.0, si usa .NET 2.0 / 3.5, debe llamar a la API win32 manualmente con el valor 40 para UserProfile
linquize
Y "Mis documentos" no es lo mismo que el directorio de inicio, excepto en Windows 95, 98 y ME.
Jon Hanna
1
No olvide utilizar System.IO.Path.DirectorySeparatorChar para crear la ruta de su archivo para mantenerlo portátil.
thomiel
4
No utilice DirectorySeperatorChar manualmente. Utilice Path.Combine.
John Gietzen
14

Creo que lo que buscas es:

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

Como referencia, de hecho está contenido en mscorlib.

Matthew Scharley
fuente
Eso devuelve la carpeta Mis documentos.
MiffTheFox
"Mis documentos" es lo más parecido que tiene Windows a un directorio personal.
MSalters
8
@MStallers No,% HOMEDRIVE %% HOMEPATH% es.
MiffTheFox
No del todo ... pero la alternativa es PInvoke, y el OP solicitó una solución administrada.
Matthew Scharley
7
Tenga en cuenta que Environment.SpecialFolder.UserProfile está disponible en .NET 4.0, que es lo que desea
linquize el
8

En DotNetCore 1.1 System.Environment.SpecialFolderno existe. Podría existir en 2.0-beta. Hasta entonces, para hacer esto puedes usar lo siguiente:

var envHome = RuntimeInformation.IsOSPlatform(OSPlatform.Windows) ? "HOMEPATH" : "HOME";
var home = Environment.GetEnvironmentVariable(envHome);`
KBP
fuente
Estoy usando 2.0 y System.Environment.SpecialFolderexiste
snotyak
4

La respuesta final es No. No hay un método simple basado en el sistema en .NET para obtener el directorio de inicio, de modo que podríamos esperar una implementación tanto en .NET en Windows como en Mono.

Deberá realizar alguna detección del sistema operativo y pasar al código específico del sistema operativo.

AnthonyWJones
fuente
1

Cuando dice multiplataforma, ¿qué otros sistemas operativos necesita admitir? Es posible que deba realizar una detección simple del sistema operativo para seleccionar el método para encontrar el directorio de inicio si está ejecutando un sistema operativo que no es Windows.

Este sitio web parece ofrecer una forma de hacer lo que necesita en Windows.

John D.
fuente
A menos que esté utilizando alguna implementación inteligente del Framework Environment, GetFolder () debería funcionar en varias plataformas.
R. Martinho Fernandes
2
Debería . La implementación de MS no lo hace.
R. Martinho Fernandes
1

Esto se puede hacer usando GetEnvironmentVariableen 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'");
    }
}

Luego produce debajo de las ventanas: C:\\\\Users\\myusername\\myFolder

Tenga en cuenta que si usa

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

falla porque produce: \\Users\\myusername\\myFolder

Nicosmik
fuente
0

No tengo una máquina para probarlo, pero %HOMESHARE%podría funcionar para usted. De lo contrario, aquí hay una lista bastante buena de variables de entorno .

JP Alioto
fuente