Use HOSTFXR_PATH to resolve native hostfxr#18911
Conversation
|
I couldn't figure out the best area label to add to this PR. If you have write-permissions please help me learn by adding exactly one area label. |
|
@mateoatr will there be any changes needed on the SDK side for this? |
| { | ||
| PreloadWindowsLibrary("hostfxr.dll"); | ||
| } | ||
| HostFxrPath = (string)AppContext.GetData("HOSTFXR_PATH"); |
There was a problem hiding this comment.
Check that HostFxrPath? I don't know if the code here can assume that the hosting bits launching it have the HOSTFXR_PATH change.
There was a problem hiding this comment.
Technically it should be able to make that assumption (SDK is bound to a version of runtime), but I agree it would be a good idea to somehow handle the error more gracefully.
I don't think we need any more changes than the ones in this PR. |
| if (!string.IsNullOrEmpty(HostFxrPath)) | ||
| NativeLibrary.SetDllImportResolver(typeof(Interop).Assembly, HostFxrDllImportResolver); |
There was a problem hiding this comment.
We might want to fail if he hostfxr path is not available. Mainly because we know it is somewhat random if it will work without the resolver. In short we think this should never happen, but it's better to have diagnostics for this.
| if (libraryName != Constants.HostFxr || !NativeLibrary.TryLoad(HostFxrPath, out IntPtr handle)) | ||
| return IntPtr.Zero; |
There was a problem hiding this comment.
Same here - if it's possible to have some diagnostics... I think it would be better to fail with clear error if we fail to load the library (for whatever reason).
| { | ||
| return new Command("check", LocalizableStrings.AppFullName); | ||
| } | ||
| catch (FileNotFoundException e) |
There was a problem hiding this comment.
It seems weird that we'd have to catch the exception on just getting the command. I'd expect it to be when the command is actually executed?
There was a problem hiding this comment.
Is this because it is in the static constructor for the Interop class / something else using the class before the command execution?
I think exceptions in static constructors also come through as TypeInitializationException.
There was a problem hiding this comment.
It seems weird that we'd have to catch the exception on just getting the command.
Agreed. I moved this to the place where we actually execute the command. Also catching TypeInitializationException now -- I wasn't aware of this.
| } | ||
| catch (ArgumentException e) | ||
| { | ||
| throw new GracefulException(string.Format(LocalizableStrings.HostFxrCouldNotBeLoaded, e.Message)); |
There was a problem hiding this comment.
The direct map of FileNotFoundException / ArgumentException to RuntimePropertyNotFound / HostFxrCouldNotBeLoaded also seems unnatural.
- Could other issues result in FileNotFoundException / ArgumentException?
- I don't know how I would make the connection between the exceptions caught here and the ones thrown in NativeWrapper Interop
There was a problem hiding this comment.
Also, I think the messages are flipped. ArgumentException is being thrown for the runtime property, not loading hostfxr.
There was a problem hiding this comment.
Could other issues result in FileNotFoundException / ArgumentException?
Good point. I added a new type of exception for the exceptions related to the hostfxr path resolution thrown in NativeWrapper.Interop. Fixed the messages as well.
5f225fc to
b8e970e
Compare
Throw from HostFxrDllImportResolver
…nto sdkCheckDllImport
The runtime property
HOSTFXR_PATHis set by the muxer when executing an SDK and stores hostfxr's fullpath. Use this property in the NativeWrapper to resolve hostfxr using a fullpath instead of relying ondlopen/LoadLibrarybehavior.This fixes dotnet/runtime#54965.
dotnet sdk checkbefore changes:After changes (tested locally on an M1):