C # obteniendo la ruta de% AppData%


387

C # 2008 SP1

Estoy usando el siguiente código:

dt.ReadXml("%AppData%\\DateLinks.xml");

Sin embargo, recibo una excepción que apunta a la ubicación desde donde se ejecuta mi aplicación:

No se pudo encontrar una parte de la ruta 'D: \ Proyectos \ SubVersionProjects \ CatDialer \ bin \ Debug \% AppData% \ DateLinks.xml'.

Pensé que %AppData%debería encontrar el camino relativo. Cuando voy, Start|Run|%AppData%Windows Explorer me lleva a ese directorio.

No puedo poner la ruta completa, ya que el usuario es diferente en cada máquina cliente.

Respuestas:


802

Para obtener el directorio AppData , es mejor usar el GetFolderPathmétodo:

Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData)

(debe agregar using Systemsi no está presente).

%AppData%es una variable de entorno, y no se expanden automáticamente en ningún lugar de .NET, aunque puede usar explícitamente el Environment.ExpandEnvironmentVariablemétodo para hacerlo. Sin embargo, sugeriría encarecidamente que lo use GetFolderPath, porque, como señala Johannes Rössel en el comentario, es %AppData%posible que no se establezca en determinadas circunstancias.

Finalmente, para crear la ruta como se muestra en su ejemplo:

var fileName = Path.Combine(Environment.GetFolderPath(
    Environment.SpecialFolder.ApplicationData), "DateLinks.xml");

45
+1 por ofrecer una solución real, no depender del medio ambiente. Para agregar a la respuesta: no todas las funciones que manejan nombres de archivo expanden las variables de entorno. De hecho, generalmente tiene que hacer esto explícitamente, de lo contrario no funcionará y terminará con% algo% carpetas. Además, el entorno no necesita estar presente, en algunos casos, cuando se ejecuta un programa con otra cuenta de usuario, el entorno del usuario no se cargará y% Appdata% estará vacío. Es por eso que desearía usar las API documentadas para obtener esas carpetas (a menos que esté usando archivos por lotes).
Joey

@Johannes: Buena información allí. Acabo de enmendar mi respuesta cuando la publicaste, pero dejaré en claro que GetFolderPath es definitivamente preferible a ExpandEnvironmentVariable.
Noldorin

+1 para Environment.GetFolderPath (Environment.SpecialFolder.ApplicationData), estuve detrás de esto durante un par de días.
Sumit Ghosh

1
Por alguna razón, me Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData)devuelve una cadena vacía (IIS 7, VS 2011). Problema resuelto usando la solución Simon_Weaver - mapeo usando MapPath.
Mike Keskinov

52
FYI que proporciona el directorio de roaming para AppData Environment.GetFolderPath (Environment.SpecialFolder.LocalApplicationData)
local

49

La ruta es diferente si estás hablando de ASP.NET.

No pude encontrar ninguno de los valores 'SpecialFolder' que apuntaban a / App_Data para ASP.NET.

En cambio, debes hacer esto:

 HttpContext.Current.ApplicationInstance.Server.MapPath("~/App_Data")  

(Nota: no necesita la propiedad 'Actual' en un controlador MVC)

Si hay otra forma más 'abstracta' de llegar App_Data, me encantaría saber cómo.


Solo una nota ya que asp.net core está saliendo ahora. Este enfoque se basa específicamente en IIS.
George Mauer

77
HostingEnvironment.MapPath(@"~/App_Data")es mejor y funciona en contextos MVC / WebAPI y WCF donde no hay HttpContext, pero no estoy seguro sobre core '
Simon_Weaver

37

La MEJOR manera de usar el directorio AppData, es usar el Environment.ExpandEnvironmentVariablemétodo.

Razones:

  • reemplaza partes de su cadena con directorios válidos o lo que sea
  • no distingue entre mayúsculas y minúsculas
  • es fácil y sin complicaciones
  • es un estándar
  • bueno para lidiar con la entrada del usuario

Ejemplos:

string path;
path = @"%AppData%\stuff";
path = @"%aPpdAtA%\HelloWorld";
path = @"%progRAMfiLES%\Adobe;%appdata%\FileZilla"; // collection of paths

path = Environment.ExpandEnvironmentVariables(path);
Console.WriteLine(path);

Recuerde que algunos usuarios escriben %AppData%, algunos %appdata%y otros %APpData% . No desea terminar con:

if (path.ToLower().StartsWith("%appdata%"))
    ; // path manipulation
if (path.ToLower().StartsWith("%programfiles%"))
    ; // path manipulation

Si la variable de entorno no está configurada, no es su culpa (además de cuando ES ). Por lo general, no les digo a las personas que no reinventen la rueda, pero después de que fui por el otro lado y me di cuenta de que era una mala idea.


Me gustaron tus ejemplos de pathvariable :)
RBT

+1 Environment.ExpandEnvironmentVariablees mejor cuando simplemente necesita expandirse, independientemente de qué entornos puedan estar en la cadena de ruta.
blins

24

También puedes usar

Environment.ExpandEnvironmentVariables("%AppData%\\DateLinks.xml");

para expandir la %AppData%variable.


15

En .net2.0 puedes usar la variable Application.UserAppDataPath


20
Esto es solo Winforms.

7

No creo que poner% AppData% en una cadena como esa funcione.

tratar

Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData).ToString()

4

Solo quería compartir otra forma de acceder a la carpeta 'App_Data' en mi aplicación mvc en caso de que alguien lo necesite.

 Path.Combine(HttpRuntime.AppDomainAppPath,"App_Data")

Puede que no sea la respuesta correcta, pero es lo que estaba buscando. +1
Derrick

Me funcionó después de reemplazar comillas simples con comillas dobles. Path.Combine (HttpRuntime.AppDomainAppPath, "App_Data")
ajaysinghdav10d

1

Esto está funcionando para mí en una aplicación de consola:

string appData = System.Environment.GetEnvironmentVariable("APPDATA");

1

Para ASP.NET, la Load User Profileconfiguración debe establecerse en el grupo de aplicaciones, pero eso no es suficiente. Hay una configuración oculta nombrada setProfileEnvironmenten \Windows\System32\inetsrv\Config\applicationHost.config, que por alguna razón está desactivada de manera predeterminada, en lugar de activarse como se describe en la documentación . Puede cambiar el valor predeterminado o establecerlo en su grupo de aplicaciones. Todos los métodos de la Environmentclase devolverán los valores adecuados.

Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.