September 1, 2004

How to get the .NET applications path?

In VB6 you can simply write App.Path to get the path to the application. But there is also many confusion about ‘what is the application path’?

With .NET there might be many different definitions of the applications-path:

  • The directory where the executable (EXE) is located
  • The current working directory
  • The directory where the current assembly is located (might be a DLL)

In the following we assume that application-path is the directory of the executable (EXE)

For .NET you have many possible ways to get the executable path:

  • Path.DirectoryName(Application.ExecutablePath)
  • Application.StartupPath
  • Path.DirectoryName(Environment.GetCommandLineArgs()[0])
  • Path.DirectoryName(System.Diagnostics.Process.GetCurrentProcess().MainModule.FileName)
  • Path.DirectoryName(Assembly.GetEntryAssembly().Location)

If you look into the implementation of Application.StartupPath you will see that it is using the native GetModuleFileName function. So this call really gets the directory of the executable (EXE).

Application.ExecutablePath instead is using a difficult method to the the correct result. The simplest way would be to also use GetModuleFileName. But they first try to call Assembly.GetEntryAssembly which also returns the first executed assembly (normally this is also the EXE).

If you do not want to add a reference to the System.Windows.Forms assembly (maybe if you are wrining an console app), the you have to use other functions. You have the following choices:

  • call the unmanaged GetModuleFileName
  • use Assembly.GetEntryAssembly

Here is solution with GetModuleFileName:

  public class App
  {
    [System.Runtime.InteropServices.DllImport(“kernel32.dll”, SetLastError=true)]
    [System.Security.SuppressUnmanagedCodeSecurity]
    private static extern uint GetModuleFileName(
      [System.Runtime.InteropServices.In]
        IntPtr hModule,
      [System.Runtime.InteropServices.Out]
        System.Text.StringBuilder lpFilename,
      [System.Runtime.InteropServices.In]
      [System.Runtime.InteropServices.MarshalAs(
        System.Runtime.InteropServices.UnmanagedType.U4)]
        int nSize
    );

    public static string StartupPath
    {
      get
      {
        System.Text.StringBuilder sb = new System.Text.StringBuilder(260);
        if (GetModuleFileName(System.IntPtr.Zero, sb, sb.Capacity) == 0)
          throw new System.ApplicationException(“Could not retrive module file name”);
        return System.IO.Path.GetDirectoryName(sb.ToString());
      }
    }
  }

Posted 3 years, 5 months ago on September 1, 2004
The trackback url for this post is http://blog.kalmbachnet.de/bblog/trackback.php/7/

Comments have now been turned off for this post