570

I see that there are some ways to get the application folder path:

  1. Application.StartupPath
  2. System.IO.Path.GetDirectoryName( System.Reflection.Assembly.GetExecutingAssembly().Location)
  3. AppDomain.CurrentDomain.BaseDirectory
  4. System.IO.Directory.GetCurrentDirectory()
  5. Environment.CurrentDirectory
  6. System.IO.Path.GetDirectoryName( System.Reflection.Assembly.GetExecutingAssembly().GetName().CodeBase)
  7. System.IO.Path.GetDirectory(Application.ExecutablePath)

What is the best way depending on the situation?

Peter Mortensen
  • 28,342
  • 21
  • 95
  • 123
Leo Vo
  • 8,802
  • 9
  • 53
  • 77
  • 10
    Why we have a lot ways to get application' path. I think there is a reason for each way. – Leo Vo May 18 '11 at 07:43
  • 1
    There is a error in #6: should read: System.Reflection.Assembly.GetExecutingAssembly().GetName().CodeBase), System.IO.Path.GetDirectoryName(Application.ExecutablePath) – BillW Nov 06 '14 at 15:33
  • 2
    hooray for #6, while I'm in a web project, I did not want Server.MapPath logic in my IoC loaded library which is not web-specific in nature – bkwdesign Mar 26 '19 at 18:13
  • 1
    We now have the reliable `IHostEnvironment.ContentRootPath`, accessed through an injected `IHostEnvironment` dependency (which contains other useful things). – Timo Nov 04 '19 at 16:15
  • There is also `Process.GetCurrentProcess().MainModule.FileName`. – nawfal Oct 06 '20 at 11:50
  • #4 and #5 are incorrect. They return the current directory, not the directory in which the application is located. (They are sometimes the same, but it's just a coincidence when that's the case.) – ikegami Jan 08 '21 at 21:59

10 Answers10

573

AppDomain.CurrentDomain.BaseDirectory is probably the most useful for accessing files whose location is relative to the application install directory.

In an ASP.NET application, this will be the application root directory, not the bin subfolder - which is probably what you usually want. In a client application, it will be the directory containing the main executable.

In a VSTO 2005 application, it will be the directory containing the VSTO managed assemblies for your application, not, say, the path to the Excel executable.

The others may return different directories depending on your environment - for example see @Vimvq1987's answer.

CodeBase is the place where a file was found and can be a URL beginning with http://. In which case Location will probably be the assembly download cache. CodeBase is not guaranteed to be set for assemblies in the GAC.

UPDATE These days (.NET Core, .NET Standard 1.3+ or .NET Framework 4.6+) it's better to use AppContext.BaseDirectory rather than AppDomain.CurrentDomain.BaseDirectory. Both are equivalent, but multiple AppDomains are no longer supported.

Joe
  • 114,633
  • 27
  • 187
  • 321
  • 2
    When testing in Windows XP 32bit, it returns where the shortcut started. – Joshua Son Dec 07 '13 at 02:37
  • 1
    +1 @Joe and For VSTO document-level add-in see [**THIS**](http://stackoverflow.com/questions/22809950/how-do-i-assign-a-relative-path-of-an-embed-image-to-a-activesheet-pagesetup-lef) –  Apr 03 '14 at 09:15
  • 3
    Be aware that this returns a path with a backslash at the end. This caused me problems when formatting a string with the result to pass as a process argument. – avenmore Nov 06 '15 at 12:18
  • 21
    @avenmore - If you're formatting a string to build a path, consider using `Path.Combine` instead. This will take care of the trailing backslash for you. – Joe Nov 06 '15 at 13:09
  • @joe: It was just a gotcha when using "args = string.Format("-p\"{0}\" -sFalse -lTrue", AppDomain.CurrentDomain.BaseDirectory);" - results in an unescaped quote. Used Path.GetDirectoryName(AppDomain.CurrentDomain.BaseDirectory) to trim it. – avenmore Nov 06 '15 at 13:28
  • Just pointing out the solution for a ASP.NET bin folder is: System.IO.Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().GetName().CodeBase) Note however, it will be prefixed with "file:\\" (which can be fixed with [.Replace("file:\\", "")]). – TinyRacoon Oct 05 '17 at 16:20
  • 1
    This is returning the bin/debug folder for me in VS 2017, not the root directory. – SmoveBB Apr 11 '19 at 14:52
  • @SmoveBB - what's the project type? `bin\debug` is the folder containing the executable – Joe Apr 11 '19 at 17:59
  • @Joe, for .NET Core 2.2, AppDomain.CurrentDomain.BaseDirectory => "SLN_FOLDER\PROJ_FOLDER\bin\Debug\netcoreapp2.2\" – Captain Prinny Jul 23 '19 at 20:19
  • Running command line from %USERPROFILE% folder. Program is at D:\somwhere-else\program.exe, `AppContext.BaseDirectory` This code return different locations. On build, it returns bin\Release\net5.0. On publish it returns temporary folder. – vee Jan 15 '21 at 21:18
104
  1. Application.StartupPathand 7. System.IO.Path.GetDirectoryName(Application.ExecutablePath) - Is only going to work for Windows Forms application

  2. System.IO.Path.GetDirectoryName( System.Reflection.Assembly.GetExecutingAssembly().Location)

    Is going to give you something like: "C:\\Windows\\Microsoft.NET\\Framework\\v4.0.30319\\Temporary ASP.NET Files\\legal-services\\e84f415e\\96c98009\\assembly\\dl3\\42aaba80\\bcf9fd83_4b63d101" which is where the page that you are running is.

  3. AppDomain.CurrentDomain.BaseDirectory for web application could be useful and will return something like "C:\\hg\\Services\\Services\\Services.Website\\" which is base directory and is quite useful.

  4. System.IO.Directory.GetCurrentDirectory() and 5. Environment.CurrentDirectory

will get you location of where the process got fired from - so for web app running in debug mode from Visual Studio something like "C:\\Program Files (x86)\\IIS Express"

  1. System.IO.Path.GetDirectoryName( System.Reflection.Assembly.GetExecutingAssembly().GetName().CodeBase)

will get you location where .dll that is running the code is, for web app that could be "file:\\C:\\hg\\Services\\Services\\Services.Website\\bin"

Now in case of for example console app points 2-6 will be directory where .exe file is.

Hope this saves you some time.

legend1337
  • 13
  • 5
Matas Vaitkevicius
  • 49,230
  • 25
  • 212
  • 228
57

Note that not all of these methods will return the same value. In some cases, they can return the same value, but be careful, their purposes are different:

Application.StartupPath

returns the StartupPath parameter (can be set when run the application)

System.IO.Directory.GetCurrentDirectory()

returns the current directory, which may or may not be the folder where the application is located. The same goes for Environment.CurrentDirectory. In case you are using this in a DLL file, it will return the path of where the process is running (this is especially true in ASP.NET).

Peter Mortensen
  • 28,342
  • 21
  • 95
  • 123
Quan Mai
  • 13,021
  • 27
  • 90
  • 125
9

For a web application, to get the current web application root directory, generally call by web page for the current incoming request:

HttpContext.Current.Server.MapPath();

System.Web.Hosting.HostingEnvironment.ApplicationPhysicalPath;

Above code description

Peter Mortensen
  • 28,342
  • 21
  • 95
  • 123
Raj kumar
  • 995
  • 11
  • 17
6

I started a process from a Windows Service over the Win32 API in the session from the user which is actually logged in (in Task Manager session 1 not 0). In this was we can get to know, which variable is the best.

For all 7 cases from the question above, the following are the results:

Path1: C:\Program Files (x86)\MyProgram
Path2: C:\Program Files (x86)\MyProgram
Path3: C:\Program Files (x86)\MyProgram\
Path4: C:\Windows\system32
Path5: C:\Windows\system32
Path6: file:\C:\Program Files (x86)\MyProgram
Path7: C:\Program Files (x86)\MyProgram

Perhaps it's helpful for some of you, doing the same stuff, when you search the best variable for your case.

Bhargav Rao
  • 41,091
  • 27
  • 112
  • 129
Beetee
  • 333
  • 1
  • 8
  • 18
4

In my experience, the best way is a combination of these.

  1. System.Reflection.Assembly.GetExecutingAssembly().GetName().CodeBase Will give you the bin folder
  2. Directory.GetCurrentDirectory() Works fine on .Net Core but not .Net and will give you the root directory of the project
  3. System.AppContext.BaseDirectory and AppDomain.CurrentDomain.BaseDirectory Works fine in .Net but not .Net core and will give you the root directory of the project

In a class library that is supposed to target.Net and .Net core I check which framework is hosting the library and pick one or the other.

Ahmed Mansour
  • 435
  • 5
  • 11
  • Re "*will give you the root directory of the project*", No, it gives the current directory, which could by any directory – ikegami Jan 08 '21 at 22:04
1

I have used this one successfully

System.IO.Path.GetDirectoryName(Process.GetCurrentProcess().MainModule.FileName)

It works even inside linqpad.

camilohe
  • 439
  • 5
  • 12
  • 2
    this is missing the opening bracket of GetCurrentProcess. btw it evaluates to C:\Program Files\dotnet in my .net core project while debugging in visual studio because thats where dotnet.exe is located – t0b4cc0 Jan 01 '18 at 18:45
0

Root directory:

DriveInfo cDrive = new DriveInfo(System.Environment.CurrentDirectory);
var driverPath = cDrive.RootDirectory;
  • 1
    This appears to get the current working directory, while that may be useful sometimes, it is definitely not guaranteed to be the EXE path. – krowe2 May 21 '19 at 14:37
-1

this one System.IO.Path.GetDirectory(Application.ExecutablePath) changed to System.IO.Path.GetDirectoryName(Application.ExecutablePath)

Kiran Shahi
  • 6,458
  • 6
  • 31
  • 60
nazim hatipoglu
  • 616
  • 11
  • 24
-1

If you know to get the root directory:

string rootPath = Path.GetPathRoot(Application.StartupPath)