477

C# 2008 SP1

I am using the code below:

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

However, I am getting an exception that points to the location of where my application is running from:

Could not find a part of the path 'D:\Projects\SubVersionProjects\CatDialer\bin\Debug\%AppData%\DateLinks.xml'.

I thought the %AppData% should find the relative path. When I go Start|Run|%AppData% windows explorer takes me to that directory.

I can not put the full path in, as the user is different on each client machine.

Tot Zam
  • 8,406
  • 10
  • 51
  • 76
ant2009
  • 27,094
  • 154
  • 411
  • 609

11 Answers11

980

To get the AppData directory, it's best to use the GetFolderPath method:

Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData)

(must add using System if not present).

%AppData% is an environment variable, and they are not automatically expanded anywhere in .NET, although you can explicitly use the Environment.ExpandEnvironmentVariable method to do so. I would still strongly suggest that you use GetFolderPath however, because as Johannes Rössel points out in the comment, %AppData% may not be set in certain circumstances.

Finally, to create the path as shown in your example:

var fileName = Path.Combine(Environment.GetFolderPath(
    Environment.SpecialFolder.ApplicationData), "DateLinks.xml");
John Cummings
  • 1,949
  • 3
  • 22
  • 38
Noldorin
  • 144,213
  • 56
  • 264
  • 302
  • 52
    +1 for offering a real solution, not relying on the environment. To add to the answer: Not every function that handles file names expands environment variables. In fact, usually you have to explicitly do this, otherwise it doesn't work and you'll end up with %something% folders. Furthermore, the environment does not need to be present, in some cases when running a program under another user account the user's environment will not be loaded and %Appdata% will be empty. That's why you would want to use the documented APIs for getting those folders (unless you're using batch files, though). – Joey May 15 '09 at 08:06
  • @Johannes: Good info there. I just amended my answer as you posted that, but I'll make it clearer that GetFolderPath is definitely preferable over ExpandEnvironmentVariable. – Noldorin May 15 '09 at 08:11
  • +1 for Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), I was behind this for couple of days now. – Sumit Ghosh May 28 '10 at 13:43
  • 1
    For some reason `Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData)` returns empty string for me (IIS 7, VS 2011). Problem solved using Simon_Weaver solution - mapping using `MapPath`. – Mike Keskinov May 21 '12 at 19:16
  • 73
    FYI that gives the Roaming directory for local AppData Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData) – roundcrisis Jul 04 '12 at 11:21
  • Thank you for the link to `Environment.ExpandEnvironmentVariable`. Certainly it's better to use GetFolderPath where possible, but there can be legitimate reasons to use the `%` form, such as when the value is in a config file. – Ryan Lundy Sep 30 '19 at 08:52
  • 1
    In Linux Docker containers, `Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData)` usually returns empty string because the folder does not exist. `Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData, Environment.SpecialFolderOption.Create)` creates the folder and returns the path (e.g. `/root/.config`). – Palec Aug 24 '21 at 09:31
80

The BEST way to use the AppData directory, IS to use Environment.ExpandEnvironmentVariables method.

Reasons:

  • it replaces parts of your string with valid directories or whatever
  • it is case-insensitive
  • it is easy and uncomplicated
  • it is a standard
  • good for dealing with user input

Examples:

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

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

More info:

%ALLUSERSPROFILE%   C:\ProgramData
%APPDATA%   C:\Users\Username\AppData\Roaming
%COMMONPROGRAMFILES%    C:\Program Files\Common Files
%COMMONPROGRAMFILES(x86)%   C:\Program Files (x86)\Common Files
%COMSPEC%   C:\Windows\System32\cmd.exe
%HOMEDRIVE% C:
%HOMEPATH%  C:\Users\Username
%LOCALAPPDATA%  C:\Users\Username\AppData\Local
%PROGRAMDATA%   C:\ProgramData
%PROGRAMFILES%  C:\Program Files
%PROGRAMFILES(X86)% C:\Program Files (x86) (only in 64-bit version)
%PUBLIC%    C:\Users\Public
%SystemDrive%   C:
%SystemRoot%    C:\Windows
%TEMP% and %TMP%    C:\Users\Username\AppData\Local\Temp
%USERPROFILE%   C:\Users\Username
%WINDIR%    C:\Windows
Avram
  • 4,267
  • 33
  • 40
Bitterblue
  • 13,162
  • 17
  • 86
  • 124
51

The path is different if you're talking ASP.NET.

I couldn't find any of the 'SpecialFolder' values that pointed to /App_Data for ASP.NET.

Instead you need to do this:

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

(Note: You don't need the 'Current' property in an MVC Controller)

If theres another more 'abstract' way to get to App_Data would love to hear how.

Simon_Weaver
  • 140,023
  • 84
  • 646
  • 689
  • Just a note since asp.net core is coming out now. This approach relies specifically on IIS. – George Mauer Aug 10 '16 at 16:00
  • 8
    `HostingEnvironment.MapPath(@"~/App_Data")` is better and works in both MVC / WebAPI and WCF contexts where there is no HttpContext - but not sure about core' – Simon_Weaver Sep 17 '16 at 11:44
28

You can also use

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

to expand the %AppData% variable.

Avishek
  • 1,896
  • 14
  • 33
parapet
  • 1,831
  • 1
  • 13
  • 6
16

In .net2.0 you can use the variable Application.UserAppDataPath

Nathan
  • 11,938
  • 12
  • 55
  • 62
14

AppData ⇝ Local aka (C:\Users\<user>\AppData\Local):

Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData)

AppData ⇝ Roaming aka (C:\Users\<user>\AppData\Roaming):

Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData)

Additionally, it could be handy to know:

  • Environment.SpecialFolder.ProgramFiles - for Program files X64 folder
  • Environment.SpecialFolder.ProgramFilesX86 - for Program files X86 folder

For the full list check here.

Arsen Khachaturyan
  • 7,904
  • 4
  • 42
  • 42
7

I don't think putting %AppData% in a string like that will work.

try

Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData).ToString()
danswain
  • 4,171
  • 5
  • 37
  • 43
3

Just wanted to share another way of accessing 'App_Data' folder in my mvc application in case that someone needs this.

 Path.Combine(HttpRuntime.AppDomainAppPath,"App_Data")
cpoDesign
  • 8,953
  • 13
  • 62
  • 106
1

This is working for me in a console application -

string appData = System.Environment.GetEnvironmentVariable("APPDATA");
Bill
  • 3,806
  • 5
  • 33
  • 45
1

For ASP.NET, the Load User Profile setting needs to be set on the app pool but that's not enough. There is a hidden setting named setProfileEnvironment in \Windows\System32\inetsrv\Config\applicationHost.config, which for some reason is turned off by default, instead of on as described in the documentation. You can either change the default or set it on your app pool. All the methods on the Environment class will then return proper values.

MoonStom
  • 2,847
  • 1
  • 26
  • 21
1
Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData);
willcodes
  • 33
  • 6