77

I tried to get the directory of the console application using the below code,

Assembly.GetExecutingAssembly().Location

but this one gives me where the assemble resides. This may be different from where I executed the application.

My console application parses logs with no parameters. It must go to the logs/ folder inside of the executable's folder or if I give it a path to logs/ it parses it.

Ryan Gates
  • 4,501
  • 6
  • 50
  • 90
eugeneK
  • 10,750
  • 19
  • 66
  • 101
  • Have a look at this question: http://stackoverflow.com/questions/674857/should-i-use-appdomain-currentdomain-basedirectory-or-system-environment-current – Karsten Oct 03 '14 at 06:40
  • you want the myapp.exe that you double clicked on to run, right? not the dlls?? try ``GetEntryAssembly`` – bh_earth0 Mar 01 '22 at 10:28

5 Answers5

120

Use Environment.CurrentDirectory.

Gets or sets the fully qualified path of the current working directory.
(MSDN Environment.CurrentDirectory Property)

string logsDirectory = Path.Combine(Environment.CurrentDirectory, "logs");

If your application is running in c:\Foo\Bar logsDirectory will point to c:\Foo\Bar\logs.

Stefan
  • 14,530
  • 4
  • 55
  • 62
  • 33
    Current Directory is different from the directory containing the current executable. – KFL May 20 '16 at 00:02
  • 1
    Environment.CurrentDirectory is a value that can and will change through the course of running your application. For instance, using default parameters, the OpenFileDialog in WinForms will change this value to the directory where the file was selected from – Jaime Marín Jan 23 '18 at 16:45
  • @KFL Yes, but the OP seems to want the dir of where the exe was executed. So this is the correct answer... – Storm Muller Oct 25 '21 at 22:18
50

Use this :

System.Reflection.Assembly.GetExecutingAssembly().Location

Combine that with

System.IO.Path.GetDirectoryName if all you want is the directory.
Sunny
  • 3,185
  • 8
  • 34
  • 66
  • 3
    If I use Environment.CurrentDirectory which run under Scheduled Task, it will goes to C:\Windows\system32\log which is not the execution path. Then I use this System.Reflection.Assembly.GetExecutingAssembly().Location, it points to my correct exe execution path. Thanks! – LifeiSHot Nov 30 '17 at 09:11
  • This might not work as you hope in unit tests or web projects running local IIS. The `CodeBase` answer does. – Timo Jan 15 '18 at 15:38
14

Scott Hanselman has a blog post with the following:

using System;
using System.Diagnostics;
using System.IO;
 
namespace testdir
{
    class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine($"Launched from {Environment.CurrentDirectory}");
            Console.WriteLine($"Physical location {AppDomain.CurrentDomain.BaseDirectory}");
            Console.WriteLine($"AppContext.BaseDir {AppContext.BaseDirectory}");
            Console.WriteLine($"Runtime Call {Path.GetDirectoryName(Process.GetCurrentProcess().MainModule.FileName)}");
        }
    }

which he uses in .NET Core 3.1, however, I'm running .NET 4.8 and it's working for me.

MikeT
  • 2,530
  • 25
  • 36
8

Safest way:

string temp = Path.GetDirectoryName(Assembly.GetExecutingAssembly().CodeBase);
dtsg
  • 4,408
  • 4
  • 30
  • 40
  • 7
    The CodeBase is a URL to the place where the file was found, while the Location is the path from where it was actually loaded. For example, if the assembly was downloaded from the internet, its CodeBase may start with "http://", but its Location may start with "C:\". If the file was shadow copied, the Location would be the path to the copy of the file in the shadow-copy dir. It’s also good to know that the CodeBase is not guaranteed to be set for assemblies in the GAC. Location will always be set for assemblies loaded from disk, however. – Erik Philips Apr 21 '14 at 18:19
  • 5
    Being sure the file is on disk, I use this version to get a "regular" path instead of a `file://` path: `Path.GetDirectoryName(new Uri(this.GetType().Assembly.GetName().CodeBase).LocalPath)` – Timo Jan 15 '18 at 15:37
4

Here is a simple logging method

using System.IO;
private static void logWrite(string filename, string text)
{
    string filepath = Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().Location) + "\\" + filename;

    using (StreamWriter sw = File.AppendText(filepath))
    {
        sw.WriteLine(text);
        Console.WriteLine(text);
    }
}

Usage:

logWrite("Log.txt", "Test");
Donovan Phoenix
  • 1,351
  • 1
  • 10
  • 8