Getting the Executable’s Directory at Run-Time (.NET)

The design of .NET makes this an interesting discussion.

Microsoft social moderator David M. Morton makes the point

Please don’t use System.Windows.Forms.Application.StartupPath unless you’re actually writing a Windows Forms application. There’s no need to add an unneeded reference to the project. Please use Assembly.GetEntryAssembly to figure out which assembly is the startup assembly in a project that is not a Windows Forms project.

11 May 2009

Further discussion on this thread

Assembly.GetExecutingAssembly().Location will return the directory of the executing DLL. You know, good thing you brought this up. I think it would actually be better to use


Instead, because that would give you the first assembly that was executed (the executable) on the off-chance that you call GetExecutingAssembly() from the GAC, you’d get a directory path that would point to the GAC, in case you managed to register your library.

I believe the best option in this case, however (From one of Boban’s posts) might actually be


Although, I’m not completely sure why this is a better option than GetEntryAssembly() would be. I think it may be because of the lack of having to call into Reflection methods, but I personally don’t see any problem with it, as long as it doesn’t kill your performance. I will say that calling the AppDomain version is good if you don’t want to have to pass the string into the Path method for GetDirectoryName.

16 December 2008

This entry was posted in Programming and tagged , , , , , , , , , . Bookmark the permalink.

2 Responses to Getting the Executable’s Directory at Run-Time (.NET)

  1. Hi James.

    Yes, this is an interesting issue. Particularly in the project I’m working on now. The .Net objects are instantiated from a Windows service written in C++. The executable’s location may not really have anything to do with the .Net locations. And to further complicate things, the deployment/installation environment may be different than the debug/development environment. And sometimes Location is relative and sometimes it’s absolute.

    I ended up having to search multiple locations:
    private static IEnumerable GetSearchLocations()
    return new[] { Assembly.GetExecutingAssembly(),
    Assembly.GetCallingAssembly() }
    .Where( a => a != null )
    .Select( a => Path.GetDirectoryName( Path.GetFullPath( a.Location ) ) )
    .Concat( new[] { GetStartupDirectory() } )

    private static string GetStartupDirectory()
    var argsPointer = GetCommandLine();
    var args = Marshal.PtrToStringAuto( argsPointer );
    if( string.IsNullOrEmpty( args ) )
    return string.Empty;
    var parseChar = args[0] == '\"' ? '\"' : ' ';
    var parameters = args.Split( parseChar );
    return Path.GetDirectoryName( parameters[parseChar == ' ' ? 0 : 1] );


  2. lol wow Yes, that’s another set of wrinkles.

    Thanks for sharing, Harley.

Leave a Reply