diff --git a/src/Resolvers/Microsoft.DotNet.NativeWrapper/EnvironmentProvider.cs b/src/Resolvers/Microsoft.DotNet.NativeWrapper/EnvironmentProvider.cs index 96c203cc3f4d..487bc8f39a3d 100644 --- a/src/Resolvers/Microsoft.DotNet.NativeWrapper/EnvironmentProvider.cs +++ b/src/Resolvers/Microsoft.DotNet.NativeWrapper/EnvironmentProvider.cs @@ -59,7 +59,7 @@ private IEnumerable SearchPaths } string? dotnetExe; -#if NETCOREAPP +#if NET // The dotnet executable is loading only the .NET version of this code so there is no point checking // the current process path on .NET Framework. We are expected to find dotnet on PATH. dotnetExe = _getCurrentProcessPath(); @@ -70,12 +70,19 @@ private IEnumerable SearchPaths { string? dotnetExeFromPath = GetCommandPath(Constants.DotNet); - if (dotnetExeFromPath != null && !Interop.RunningOnWindows) +#if NET + if (dotnetExeFromPath != null && !OperatingSystem.IsWindows()) { // e.g. on Linux the 'dotnet' command from PATH is a symlink so we need to // resolve it to get the actual path to the binary - dotnetExeFromPath = Interop.Unix.realpath(dotnetExeFromPath) ?? dotnetExeFromPath; + FileSystemInfo fileInfo = new FileInfo(dotnetExeFromPath); + if ((fileInfo.Attributes & FileAttributes.ReparsePoint) != 0) + { + fileInfo = fileInfo.ResolveLinkTarget(returnFinalTarget: true) ?? fileInfo; + } + dotnetExeFromPath = fileInfo.FullName; } +#endif if (!string.IsNullOrWhiteSpace(dotnetExeFromPath)) { @@ -86,7 +93,7 @@ private IEnumerable SearchPaths log?.Invoke($"GetDotnetExeDirectory: dotnet command path not found. Using current process"); log?.Invoke($"GetDotnetExeDirectory: Path variable: {_getEnvironmentVariable(Constants.PATH)}"); -#if !NETCOREAPP +#if !NET // If we failed to find dotnet on PATH, we revert to the old behavior of returning the current process // path. This is really an error state but we're keeping the contract of always returning a non-empty // path for backward compatibility. @@ -123,7 +130,7 @@ private IEnumerable SearchPaths private static string? GetCurrentProcessPath() { string? currentProcessPath; -#if NET6_0_OR_GREATER +#if NET currentProcessPath = Environment.ProcessPath; #else currentProcessPath = Process.GetCurrentProcess().MainModule.FileName; diff --git a/src/Resolvers/Microsoft.DotNet.NativeWrapper/Interop.cs b/src/Resolvers/Microsoft.DotNet.NativeWrapper/Interop.cs index a6d9f6d808ae..07ae24fd5508 100644 --- a/src/Resolvers/Microsoft.DotNet.NativeWrapper/Interop.cs +++ b/src/Resolvers/Microsoft.DotNet.NativeWrapper/Interop.cs @@ -8,7 +8,7 @@ namespace Microsoft.DotNet.NativeWrapper public static partial class Interop { public static readonly bool RunningOnWindows = RuntimeInformation.IsOSPlatform(OSPlatform.Windows); -#if NETCOREAPP +#if NET private static readonly string? HostFxrPath; #endif @@ -18,7 +18,7 @@ static Interop() { PreloadWindowsLibrary(Constants.HostFxr); } -#if NETCOREAPP +#if NET else { HostFxrPath = (string)AppContext.GetData(Constants.RuntimeProperty.HostFxrPath)!; @@ -41,7 +41,7 @@ private static void PreloadWindowsLibrary(string dllFileName) LoadLibraryExW(dllPath, IntPtr.Zero, LOAD_WITH_ALTERED_SEARCH_PATH); } -#if NETCOREAPP +#if NET private static IntPtr HostFxrResolver(Assembly assembly, string libraryName) { if (libraryName != Constants.HostFxr) @@ -186,20 +186,6 @@ internal delegate void hostfxr_get_available_sdks_result_fn( internal static extern int hostfxr_get_available_sdks( string? exe_dir, hostfxr_get_available_sdks_result_fn result); - - [DllImport("libc", CharSet = UTF8, ExactSpelling = true, CallingConvention = CallingConvention.Cdecl)] - private static extern IntPtr realpath(string path, IntPtr buffer); - - [DllImport("libc", ExactSpelling = true, CallingConvention = CallingConvention.Cdecl)] - private static extern void free(IntPtr ptr); - - public static string? realpath(string path) - { - var ptr = realpath(path, IntPtr.Zero); - var result = PtrToStringUTF8(ptr); - free(ptr); - return result; - } } } }