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

Assembly.GetEntryAssembly().Location

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

AppDomain.CurrentDomain.BaseDirectory

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

2 thoughts on “Getting the Executable’s Directory at Run-Time (.NET)

  1. Harley Pebley

    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.GetEntryAssembly(),
    Assembly.GetCallingAssembly() }
    .Where( a => a != null )
    .Select( a => Path.GetDirectoryName( Path.GetFullPath( a.Location ) ) )
    .Concat( new[] { GetStartupDirectory() } )
    .Distinct();
    }

    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] );
    }

    Cheers,
    Harley

Leave a Reply