How to get root directory of project in asp.net core. Directory.GetCurrentDirectory() doesn't seem to work correctly on a mac
Depending on where you are in the kestrel pipeline - if you have access to IConfiguration
(Startup.cs
constructor) or IWebHostEnvironment
(formerly IHostingEnvironment
) you can either inject the IWebHostEnvironment
into your constructor or just request the key from the configuration.
Inject IWebHostEnvironment
in Startup.cs
Constructor
public Startup(IConfiguration configuration, IWebHostEnvironment env)
{
var contentRoot = env.ContentRootPath;
}
Using IConfiguration in Startup.cs Constructor
public Startup(IConfiguration configuration)
{
var contentRoot = configuration.GetValue<string>(WebHostDefaults.ContentRootKey);
}
Directory.GetCurrentDirectory() doesn't return the correct directory
This is a bug in ASP.NET Core 2.2 which has been reported in GitHub and Microsoft ASP.NET Core team has provided a solution as follows and they will add this solution to the feature release of ASP.NET Core.
Write a helper class as follows:
public class CurrentDirectoryHelpers
{
internal const string AspNetCoreModuleDll = "aspnetcorev2_inprocess.dll";
[System.Runtime.InteropServices.DllImport("kernel32.dll")]
private static extern IntPtr GetModuleHandle(string lpModuleName);
[System.Runtime.InteropServices.DllImport(AspNetCoreModuleDll)]
private static extern int http_get_application_properties(ref IISConfigurationData iiConfigData);
[System.Runtime.InteropServices.StructLayout(System.Runtime.InteropServices.LayoutKind.Sequential)]
private struct IISConfigurationData
{
public IntPtr pNativeApplication;
[System.Runtime.InteropServices.MarshalAs(System.Runtime.InteropServices.UnmanagedType.BStr)]
public string pwzFullApplicationPath;
[System.Runtime.InteropServices.MarshalAs(System.Runtime.InteropServices.UnmanagedType.BStr)]
public string pwzVirtualApplicationPath;
public bool fWindowsAuthEnabled;
public bool fBasicAuthEnabled;
public bool fAnonymousAuthEnable;
}
public static void SetCurrentDirectory()
{
try
{
// Check if physical path was provided by ANCM
var sitePhysicalPath = Environment.GetEnvironmentVariable("ASPNETCORE_IIS_PHYSICAL_PATH");
if (string.IsNullOrEmpty(sitePhysicalPath))
{
// Skip if not running ANCM InProcess
if (GetModuleHandle(AspNetCoreModuleDll) == IntPtr.Zero)
{
return;
}
IISConfigurationData configurationData = default(IISConfigurationData);
if (http_get_application_properties(ref configurationData) != 0)
{
return;
}
sitePhysicalPath = configurationData.pwzFullApplicationPath;
}
Environment.CurrentDirectory = sitePhysicalPath;
}
catch
{
// ignore
}
}
}
Then call the SetCurrentDirectory()
method in your code as follows:
app.UseStaticFiles(new StaticFileOptions {
FileProvider = new PhysicalFileProvider(
CurrentDirectoryHelpers.SetCurrentDirectory(); // call it here
Path.Combine(Directory.GetCurrentDirectory(), "StaticFiles")),
RequestPath = "/StaticFiles"
});
Now everything should work fine!
Best way to get application folder path
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.
Related Topics
A Better Way to Use Automapper to Flatten Nested Objects
Accessing a Shared File (Unc) from a Remote, Non-Trusted Domain With Credentials
Json.Net: Deserilization With Double Quotes
Reading Only Specific Columns from a CSV File Out of Many
Algorithm to Detect Overlapping Periods
How to Send a File Document to the Printer and Have It Print
How to Add a Run Button and Compile Button on the Toolbar in Visual Studio
How to Implement Async Task to Fetch Data from Database Using Async and Await
How to Delete a Read-Only File
Getting All Attributes from an Iwebelement With Selenium Webdriver
The Incoming Request Has Too Many Parameters. the Server Supports a Maximum of 2100 Parameters
Can Newtonsoft Json.Net Skip Serializing Empty Lists
How to Acces an Instance of a Class from Another Class
How to Iterate Though Each Child Node in an Xml File
Response to Preflight Request Doesn't Pass Access Control Check (Angular2)
How to Pass Parameter from @Url.Action to Controller Function
Newtonsoft.Json Serializeobject Without Escape Backslashes
How to Automatically Update an Application Without Clickonce