Directory.Getcurrentdirectory() Not Working on Linux

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!

Directory.GetCurrentDirectory() doesn't point to bin folder anymore

Thanks to Canton7 in the comments above I figured out that you should call Path.GetDirectoryName(Assembly.GetEntryAssembly().Location) instead.

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(); reporting wrong path for 2nd exe

That is the correct directory. It's the working directory where you launched that process from. If you want to change it, do it like:

string baseDir = AppDomain.CurrentDomain.BaseDirectory;
string path = baseDir + "Programs\\Logging\\";
Process logger = new Process();
// Here's the deal
logger.StartInfo.WorkingDirectory = path;
logger.StartInfo.FileName = System.IO.Path.Combine(path, "Logger.exe");
logger.Start();

Get current folder path

You should not use Directory.GetCurrentDirectory() in your case, as the current directory may differ from the execution folder, especially when you execute the program through a shortcut.

It's better to use Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location); for your purpose. This returns the pathname where the currently executing assembly resides.

While my suggested approach allows you to differentiate between the executing assembly, the entry assembly or any other loaded assembly, as Soner Gönül said in his answer,

System.IO.Path.GetDirectoryName(Application.ExecutablePath);

may also be sufficient. This would be equal to

System.IO.Path.GetDirectoryName(Assembly.GetEntryAssembly().Location);

How to get the current directory in a C program?

Have you had a look at getcwd()?

#include <unistd.h>
char *getcwd(char *buf, size_t size);

Simple example:

#include <unistd.h>
#include <stdio.h>
#include <limits.h>

int main() {
char cwd[PATH_MAX];
if (getcwd(cwd, sizeof(cwd)) != NULL) {
printf("Current working dir: %s\n", cwd);
} else {
perror("getcwd() error");
return 1;
}
return 0;
}


Related Topics



Leave a reply



Submit