7

What is the correct parameter to pass to SetBasePath for in-process hosting?

We set the configuration this way:

private static IConfiguration Configuration { get; } = new ConfigurationBuilder()
    .SetBasePath(Directory.GetCurrentDirectory())
    .AddJsonFile("appsettings.json", optional: false)
    .Build();

However, with ASP.NET Core 2.2 in-process hosting, Directory.GetCurrentDirectory() returns C:\Program Files\IIS Express instead of my application root directory.

Edit:

I am initializing my configuration in Program.Main in order to read the settings to pass to Serilog, following the example.

Answer:

This question has sadly been marked as a duplicate, thus answering in the question instead.

The issue is discussed here. The GetCurrentDirectory will give the same value as out of process hosting in the next update to ASP.NET Core. Meanwhile, the following code is provided as a workaround.

using System;

namespace SampleApp
{
    internal 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
            }
        }
    }
}
Jeow Li Huan
  • 3,758
  • 1
  • 34
  • 52
  • That was the default hosting method in IIS for ASP.NET Core in previous version. ASP.NET Core Module in IIS acts as a proxy to the out-of-process Kestrel server. – Jeow Li Huan Dec 05 '18 at 09:45
  • 4
    Give it a go with [`AppContext.BaseDirectory`](https://learn.microsoft.com/en-us/dotnet/api/system.appcontext.basedirectory?view=netframework-4.7.2) - It's used in ASP.NET Core itself. – Kirk Larkin Dec 05 '18 at 15:26

0 Answers0