Skip to content

Commit 9baf4b4

Browse files
committed
Move custom hostfxr loading logic to installation library
1 parent 174a10d commit 9baf4b4

File tree

2 files changed

+57
-50
lines changed

2 files changed

+57
-50
lines changed

src/Installer/Microsoft.Dotnet.Installation/Internal/HostFxrWrapper.cs

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,19 +5,32 @@
55
using System.Collections.Generic;
66
using System.Text;
77
using Microsoft.DotNet.NativeWrapper;
8+
using Microsoft.VisualBasic;
89

910
namespace Microsoft.Dotnet.Installation.Internal
1011
{
1112
internal class HostFxrWrapper
1213
{
1314
public static NetEnvironmentInfo getInfo(string installRoot)
1415
{
16+
if (!Directory.Exists(installRoot))
17+
{
18+
return new NetEnvironmentInfo();
19+
}
20+
PreloadHostFxrLibrary(installRoot);
21+
1522
var bundleProvider = new NETBundlesNativeWrapper();
1623
return bundleProvider.GetDotnetEnvironmentInfo(installRoot); // Could we use get_available_sdks instead to improve perf?
1724
}
1825

1926
public static IEnumerable<DotnetInstall> getInstalls(string installRoot)
2027
{
28+
if (!Directory.Exists(installRoot))
29+
{
30+
return Enumerable.Empty<DotnetInstall>();
31+
}
32+
PreloadHostFxrLibrary(installRoot);
33+
2134
var environmentInfo = getInfo(installRoot);
2235
var installs = new List<DotnetInstall>();
2336
foreach (var sdk in environmentInfo.SdkInfo.ToList())
@@ -38,5 +51,48 @@ public static IEnumerable<DotnetInstall> getInstalls(string installRoot)
3851

3952
return installs;
4053
}
54+
55+
// lpFileName passed to LoadLibraryEx must be a full path.
56+
private const int LOAD_WITH_ALTERED_SEARCH_PATH = 0x8;
57+
58+
[DllImport("kernel32.dll", CharSet = CharSet.Unicode, ExactSpelling = true, CallingConvention = CallingConvention.StdCall)]
59+
private static extern IntPtr LoadLibraryExW(string lpFileName, IntPtr hFile, int dwFlags);
60+
61+
private static void PreloadHostFxrLibrary(string dotnetExeDirectory)
62+
{
63+
string? hostFxrPath = FindHostFxrLibrary(dotnetExeDirectory);
64+
if (hostFxrPath != null)
65+
{
66+
if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
67+
{
68+
LoadLibraryExW(hostFxrPath, IntPtr.Zero, LOAD_WITH_ALTERED_SEARCH_PATH);
69+
}
70+
#if NETCOREAPP
71+
else
72+
{
73+
AppContext.SetData("HOSTFXR_PATH", hostFxrPath);
74+
}
75+
#endif
76+
}
77+
}
78+
79+
private static string? FindHostFxrLibrary(string installRoot)
80+
{
81+
string hostFxrDirectory = Path.Combine(installRoot, "host", "fxr");
82+
if (!Directory.Exists(hostFxrDirectory))
83+
{
84+
return null;
85+
}
86+
87+
string libraryName = RuntimeInformation.IsOSPlatform(OSPlatform.Windows)
88+
? "hostfxr.dll"
89+
: RuntimeInformation.IsOSPlatform(OSPlatform.OSX)
90+
? "libhostfxr.dylib"
91+
: "libhostfxr.so";
92+
93+
return Directory.EnumerateFiles(hostFxrDirectory, libraryName, SearchOption.AllDirectories)
94+
.OrderByDescending(File.GetLastWriteTimeUtc)
95+
.FirstOrDefault();
96+
}
4197
}
4298
}

src/Resolvers/Microsoft.DotNet.NativeWrapper/NETBundlesNativeWrapper.cs

Lines changed: 1 addition & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -5,64 +5,15 @@ namespace Microsoft.DotNet.NativeWrapper
55
{
66
public class NETBundlesNativeWrapper : INETBundleProvider
77
{
8-
// lpFileName passed to LoadLibraryEx must be a full path.
9-
private const int LOAD_WITH_ALTERED_SEARCH_PATH = 0x8;
10-
11-
[DllImport("kernel32.dll", CharSet = CharSet.Unicode, ExactSpelling = true, CallingConvention = CallingConvention.StdCall)]
12-
private static extern IntPtr LoadLibraryExW(string lpFileName, IntPtr hFile, int dwFlags);
13-
148
public NetEnvironmentInfo GetDotnetEnvironmentInfo(string dotnetExeDirectory)
159
{
16-
PreloadHostFxrLibrary(dotnetExeDirectory);
17-
1810
var info = new NetEnvironmentInfo();
1911
IntPtr reserved = IntPtr.Zero;
2012
IntPtr resultContext = IntPtr.Zero;
2113

22-
// If directory doesn't exist, we may not be able to load hostfxr, so treat as if there are no installed frameworks/SDKs.
23-
if (Directory.Exists(dotnetExeDirectory))
24-
{
25-
int errorCode = Interop.hostfxr_get_dotnet_environment_info(dotnetExeDirectory, reserved, info.Initialize, resultContext);
26-
}
14+
int errorCode = Interop.hostfxr_get_dotnet_environment_info(dotnetExeDirectory, reserved, info.Initialize, resultContext);
2715

2816
return info;
2917
}
30-
31-
private void PreloadHostFxrLibrary(string dotnetExeDirectory)
32-
{
33-
string? hostFxrPath = FindHostFxrLibrary(dotnetExeDirectory);
34-
if (hostFxrPath != null)
35-
{
36-
if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
37-
{
38-
LoadLibraryExW(hostFxrPath, IntPtr.Zero, LOAD_WITH_ALTERED_SEARCH_PATH);
39-
}
40-
#if NETCOREAPP
41-
else
42-
{
43-
AppContext.SetData(Constants.RuntimeProperty.HostFxrPath, hostFxrPath);
44-
}
45-
#endif
46-
}
47-
}
48-
49-
private static string? FindHostFxrLibrary(string installRoot)
50-
{
51-
string hostFxrDirectory = Path.Combine(installRoot, "host", "fxr");
52-
if (!Directory.Exists(hostFxrDirectory))
53-
{
54-
return null;
55-
}
56-
57-
string libraryName = RuntimeInformation.IsOSPlatform(OSPlatform.Windows)
58-
? "hostfxr.dll"
59-
: RuntimeInformation.IsOSPlatform(OSPlatform.OSX)
60-
? "libhostfxr.dylib"
61-
: "libhostfxr.so";
62-
63-
return Directory.EnumerateFiles(hostFxrDirectory, libraryName, SearchOption.AllDirectories)
64-
.OrderByDescending(File.GetLastWriteTimeUtc)
65-
.FirstOrDefault();
66-
}
6718
}
6819
}

0 commit comments

Comments
 (0)