pythonnet / clr-loader

Loader for different .NET runtimes
MIT License
32 stars 23 forks source link

Cannot set parameters for .net core start. AppContext.BaseDirectory cannot be set. #60

Closed joernsierwald closed 1 year ago

joernsierwald commented 1 year ago

in order to set AppContext.BaseDirectory correctly, one has to provide this during startup. The answer seems to be the following:

pythonnet.load("coreclr", properties={"APP_CONTEXT_BASE_DIRECTORY":r"c:\dev\ppp\buildOutput\binaries\x64-debug\playground"})

However, this does not actually work. While the lib has the needed function call to hostfxr_set_runtime_property_value() available, it is not actually usuable. Consider this function in hostfxr.py:

class DotnetCoreRuntime(Runtime):
    def __init__(self, runtime_config: Path, dotnet_root: Path, **params: str):
        self._handle = None

        if _IS_SHUTDOWN:
            raise RuntimeError("Runtime can not be reinitialized")

        self._dotnet_root = Path(dotnet_root)
        self._dll = load_hostfxr(self._dotnet_root)
        self._is_initialized = False
        self._handle = _get_handle(self._dll, self._dotnet_root, runtime_config)
        self._load_func = _get_load_func(self._dll, self._handle)

        for key, value in params.items():
            self[key] = value

The only place where hostfxr_set_runtime_property_value() can be called is between _get_handle and _get_load_func. Try before and the dll is not ready, try afterwards and the runtime is already loaded. Also, the for loop at the end is misguided since it can only lead to an "runtime already loaded" error. A second problem is that the "params" section of the init parameters cannot be used, as the call to this constructor is hard-coded without parameter forwarding.

Suggest action: Move the for loop to between _get_handle and _get_load_func, make the call to the constructor forward the parameters.