diff --git a/src/Ionide.ProjInfo/Library.fs b/src/Ionide.ProjInfo/Library.fs
index 05e35f98..ac717e46 100644
--- a/src/Ionide.ProjInfo/Library.fs
+++ b/src/Ionide.ProjInfo/Library.fs
@@ -154,22 +154,14 @@ module Init =
/// for more examples of this.
///
/// the versioned root path of a given SDK version, for example '/usr/local/share/dotnet/sdk/5.0.300'
- /// The full path to a dotnet binary to use as the root binary. This will be set as the DOTNET_HOST_PATH
///
- let setupForSdkVersion (sdkRoot: DirectoryInfo) (dotnetExe: FileInfo) =
+ let setupForSdkVersion (sdkRoot: DirectoryInfo) =
let msbuild = SdkDiscovery.msbuildForSdk sdkRoot
// gotta set some env variables so msbuild interop works, see the locator for details: https://github.com/microsoft/MSBuildLocator/blob/d83904bff187ce8245f430b93e8b5fbfefb6beef/src/MSBuildLocator/MSBuildLocator.cs#L289
Environment.SetEnvironmentVariable("MSBUILD_EXE_PATH", msbuild)
Environment.SetEnvironmentVariable("MSBuildExtensionsPath", ensureTrailer sdkRoot.FullName)
Environment.SetEnvironmentVariable("MSBuildSDKsPath", Path.Combine(sdkRoot.FullName, "Sdks"))
- // .net 6 sdk includes workload stuff and this breaks for some reason
- Environment.SetEnvironmentVariable("MSBuildEnableWorkloadResolver", "false")
-
- match System.Environment.GetEnvironmentVariable "DOTNET_HOST_PATH" with
- | null
- | "" -> Environment.SetEnvironmentVariable("DOTNET_HOST_PATH", dotnetExe.FullName)
- | alreadySet -> ()
if resolveHandler <> null then
AssemblyLoadContext.Default.remove_Resolving resolveHandler
@@ -196,7 +188,7 @@ module Init =
match sdkInfo with
| Some sdkInfo ->
let msbuild = SdkDiscovery.msbuildForSdk sdkInfo.Path
- setupForSdkVersion sdkInfo.Path exe
+ setupForSdkVersion sdkInfo.Path
ToolsPath msbuild
| None -> failwithf $"Unable to get sdk versions at least from the string '{dotnetSdkVersionAtPath}'. This found sdks were {sdks |> Array.toList}"
| Error (dotnetExe, args, cwd, erroringVersionString) -> failwithf $"Unable to parse sdk version from the string '{erroringVersionString}'. This value came from running `{dotnetExe} {args}` at path {cwd}"
@@ -275,7 +267,7 @@ module ProjectLoader =
[ logger; yield! loggers ]
- let getGlobalProps (path: string) (tfm: string option) (globalProperties: (string * string) list) =
+ let getGlobalProps (ToolsPath msbuildDllPath) (path: string) (tfm: string option) (globalProperties: (string * string) list) =
dict [ "ProvideCommandLineArgs", "true"
"DesignTimeBuild", "true"
"SkipCompilerExecution", "true"
@@ -284,10 +276,21 @@ module ProjectLoader =
"DefineExplicitDefaults", "true"
"BuildProjectReferences", "false"
"UseCommonOutputDirectory", "false"
+ "MSBuildEnableWorkloadResolver", "false" // some .net 6 workload stuff was breaking design-time builds
if tfm.IsSome then
"TargetFramework", tfm.Value
if path.EndsWith ".csproj" then
"NonExistentFile", Path.Combine("__NonExistentSubDir__", "__NonExistentFile__")
+ else if path.EndsWith ".fsproj" then
+ let dotnetRoot = Path.GetFullPath(Path.Combine(Path.GetDirectoryName msbuildDllPath, $"../../"))
+ // instead of setting DOTNET_HOST_PATH, set some F#-specific target properties here
+ // see https://github.com/dotnet/fsharp/blob/eccf87b7c8ea1a62dbb9481f12c5ba02ca80b8e6/src/fsharp/FSharp.Build/Microsoft.FSharp.NetSdk.props#L59-L67
+ "FscToolPath", dotnetRoot
+ "FscToolExe", Paths.dotnetBinaryName
+ "DotnetFscCompilerPath", Path.Combine(Path.GetDirectoryName msbuildDllPath, "./FSharp/fsc.dll")
+ "FsiToolPath", dotnetRoot
+ "FsiToolExe", Paths.dotnetBinaryName
+ "DotnetFsiCompilerPath", Path.Combine(Path.GetDirectoryName msbuildDllPath, "./FSharp/fsi.dll")
"DotnetProjInfo", "true"
yield! globalProperties ]
@@ -316,20 +319,20 @@ module ProjectLoader =
"_ComputeNonExistentFileProperty"
"CoreCompile" |]
- let loadProject (path: string) (binaryLogs: BinaryLogGeneration) globalProperties =
+ let loadProject toolsPath (projectPath: string) (binaryLogs: BinaryLogGeneration) globalProperties =
try
- let readingProps = getGlobalProps path None globalProperties
- let tfm = getTfm path readingProps
+ let readingProps = getGlobalProps toolsPath projectPath None globalProperties
+ let tfm = getTfm projectPath readingProps
- let globalProperties = getGlobalProps path tfm globalProperties
+ let globalProperties = getGlobalProps toolsPath projectPath tfm globalProperties
use pc = new ProjectCollection(globalProperties)
- let pi = pc.LoadProject(path, globalProperties, toolsVersion = null)
+ let pi = pc.LoadProject(projectPath, globalProperties, toolsVersion = null)
use sw = new StringWriter()
- let loggers = createLoggers [ path ] binaryLogs sw
+ let loggers = createLoggers [ projectPath ] binaryLogs sw
let pi = pi.CreateProjectInstance()
@@ -551,16 +554,17 @@ module ProjectLoader =
///
/// Main entry point for project loading.
///
- /// Full path to the `.fsproj` file
+ /// The path to the MSBuild DLL, as returned by the init function
+ /// Full path to the `.fsproj` file
/// describes if and how to generate MsBuild binary logs
/// The global properties to use (e.g. Configuration=Release). Some additional global properties are pre-set by the tool
/// List of additional MsBuild properties that you want to obtain.
/// Returns the record instance representing the loaded project or string containing error message
- let getProjectInfo (path: string) (globalProperties: (string * string) list) (binaryLogs: BinaryLogGeneration) (customProperties: string list) : Result =
- let loadedProject = loadProject path binaryLogs globalProperties
+ let getProjectInfo toolsPath (projectPath: string) (globalProperties: (string * string) list) (binaryLogs: BinaryLogGeneration) (customProperties: string list) : Result =
+ let loadedProject = loadProject toolsPath projectPath binaryLogs globalProperties
match loadedProject with
- | ProjectLoadingStatus.Success project -> getLoadedProjectInfo path customProperties project
+ | ProjectLoadingStatus.Success project -> getLoadedProjectInfo projectPath customProperties project
| ProjectLoadingStatus.Error e -> Result.Error e
/// A type that turns project files or solution files into deconstructed options.
@@ -611,7 +615,6 @@ module WorkspaceLoaderViaProjectGraph =
type WorkspaceLoaderViaProjectGraph private (toolsPath, ?globalProperties: (string * string) list) =
- let (ToolsPath toolsPath) = toolsPath
let globalProperties = defaultArg globalProperties []
let logger = LogProvider.getLoggerFor ()
let loadingNotification = new Event()
@@ -631,7 +634,7 @@ type WorkspaceLoaderViaProjectGraph private (toolsPath, ?globalProperties: (stri
let projectInstanceFactory projectPath (_globalProperties: IDictionary) (projectCollection: ProjectCollection) =
let tfm = ProjectLoader.getTfm projectPath (dict globalProperties)
//let globalProperties = globalProperties |> Seq.toList |> List.map (fun (KeyValue(k,v)) -> (k,v))
- let globalProperties = ProjectLoader.getGlobalProps projectPath tfm globalProperties
+ let globalProperties = ProjectLoader.getGlobalProps toolsPath projectPath tfm globalProperties
ProjectInstance(projectPath, globalProperties, toolsVersion = null, projectCollection = projectCollection)
let projectGraphProjs (paths: string seq) =
@@ -823,7 +826,7 @@ type WorkspaceLoader private (toolsPath: ToolsPath, ?globalProperties: (string *
cache |> Seq.map (fun n -> n.Value) |> Seq.toList
let rec loadProject p =
- let res = ProjectLoader.getProjectInfo p globalProperties binaryLogs customProperties
+ let res = ProjectLoader.getProjectInfo toolsPath p globalProperties binaryLogs customProperties
match res with
| Ok project ->
diff --git a/src/Ionide.ProjInfo/Utils.fs b/src/Ionide.ProjInfo/Utils.fs
index 1850282a..8b5aab6f 100644
--- a/src/Ionide.ProjInfo/Utils.fs
+++ b/src/Ionide.ProjInfo/Utils.fs
@@ -10,7 +10,7 @@ module Paths =
let private isLinux = RuntimeInformation.IsOSPlatform(OSPlatform.Linux)
let private isUnix = isLinux || isMac
- let private dotnetBinaryName =
+ let dotnetBinaryName =
if isUnix then
"dotnet"
else