Search code examples
.net-core.net-5

What parameters to call coreclr_initialize with?


I am calling coreclr_initialize in coreclr.dll found in C:\Program Files\dotnet\shared\Microsoft.NETCore.App\5.0.11\

I don't know if there's an official way to find the best coreclr.dll besides just using the highest version in that hardcoded path, but that seems to work (and using Program Files (x86) if it's a 32 bit process).

private static class Native
{
    [DllImport("coreclr.dll", CallingConvention=CallingConvention.Cdecl)]
    public static extern int coreclr_initialize(
        [MarshalAs(UnmanagedType.LPStr)] string exePath,
        [MarshalAs(UnmanagedType.LPStr)] string appDomainFriendlyName,
        int propertyCount,
        [MarshalAs(UnmanagedType.LPArray, ArraySubType=UnmanagedType.LPStr)] string[] propertyKeys,
        [MarshalAs(UnmanagedType.LPArray, ArraySubType=UnmanagedType.LPStr)] string[] propertyValues,
        out IntPtr hostHandle,
        out uint domainId);
}

The example code showed "TRUSTED_PLATFORM_ASSEMBLIES" as the only propertyKey, with a semicolon separated list of trusted assemblies. But I don't know where to find if there are other valid parameters that can be passed. In particular, I can't figure out how to set the AppDomain.CurrentDomain.BaseDirectory. It always shows as blank, and doesn't seem to be affected by what I pass for exePath. Are there other properties that can be set, and any that should be set?

Also related, I can't get System.Data.SqlClient to automatically load sni.dll, even if I call Kernel32.SetDllDirectory() to the directory where the sni.dll is located. The build package likes to put it in "runtimes\win-x64\native". I don't know if the DllImport behaves differently in .NET 5 in how it finds native dlls, so maybe if I could get AppDomain's BaseDirectory right it would load it automatically? If not, I can work around it by manually calling LoadLibrary("sni.dll"), but getting a BaseDirectory set correctly seems important for various reasons.

I guess there's really 2 questions here which I assume are related: what properties can be set, and how to set the BaseDirectory?


Solution

  • From the link Hans Passant shared:

    const pal::char_t *PropertyNameMapping[] =
        {
            _X("TRUSTED_PLATFORM_ASSEMBLIES"),
            _X("NATIVE_DLL_SEARCH_DIRECTORIES"),
            _X("PLATFORM_RESOURCE_ROOTS"),
            _X("APP_CONTEXT_BASE_DIRECTORY"),
            _X("APP_CONTEXT_DEPS_FILES"),
            _X("FX_DEPS_FILE"),
            _X("PROBING_DIRECTORIES"),
            _X("STARTUP_HOOKS"),
            _X("APP_PATHS"),
            _X("RUNTIME_IDENTIFIER"),
            _X("BUNDLE_PROBE"),
            _X("HOSTPOLICY_EMBEDDED"),
            _X("PINVOKE_OVERRIDE")
        };
    

    I have experimentally verified the following:

    APP_CONTEXT_BASE_DIRECTORY is used to set the AppDomain.CurrentDomain.BaseDirectory. NATIVE_DLL_SEARCH_DIRECTORIES is used to control where it loads P/Invoke dlls from.