Skip to content

Commit

Permalink
Merge pull request #119 from vxfield/xfield/fix-list-sdks2
Browse files Browse the repository at this point in the history
This PR supersedes #117.
It contains some improvements to #79 (Return all installed DotNetSDK).

Fix console output event handling
Problem: if the "dotnet --info" process runs faster and completes before we subscribe to the output events we loose its output. And we also were checking if the process completes successfully before this line we were existing without the actual list of SDKs.
Fixes:
Subscribe to output events before starting the process
Don't exit if the process has already finished
Fix to not require the base path to be present to return the full list of SDKs
Problem: the base path is not returned by "dotnet --info" if the required version (from global.json) is not found. Still, we could return the list of installed SDKs and let the caller method to decide whether or not to use the available SDKs.
Fix: if the base path is found return it, otherwise proceed to list the installed SDKs
  • Loading branch information
Forgind authored Jan 15, 2021
2 parents d8a6e34 + f0d37a7 commit 23fb66e
Showing 1 changed file with 25 additions and 29 deletions.
54 changes: 25 additions & 29 deletions src/MSBuildLocator/DotNetSdkLocationHelper.cs
Original file line number Diff line number Diff line change
Expand Up @@ -82,58 +82,54 @@ private static IEnumerable<string> GetDotNetBasePaths(string workingDirectory)
const string DOTNET_CLI_UI_LANGUAGE = nameof(DOTNET_CLI_UI_LANGUAGE);

Process process;
var lines = new List<string>();
try
{
var startInfo = new ProcessStartInfo("dotnet", "--info")
{
WorkingDirectory = workingDirectory,
CreateNoWindow = true,
UseShellExecute = false,
RedirectStandardOutput = true,
RedirectStandardError = true
process = new Process()
{
StartInfo = new ProcessStartInfo("dotnet", "--info")
{
WorkingDirectory = workingDirectory,
CreateNoWindow = true,
UseShellExecute = false,
RedirectStandardOutput = true,
RedirectStandardError = true
}
};

// Ensure that we set the DOTNET_CLI_UI_LANGUAGE environment variable to "en-US" before
// running 'dotnet --info'. Otherwise, we may get localized results.
startInfo.EnvironmentVariables[DOTNET_CLI_UI_LANGUAGE] = "en-US";
process.StartInfo.EnvironmentVariables[DOTNET_CLI_UI_LANGUAGE] = "en-US";

process.OutputDataReceived += (_, e) =>
{
if (!string.IsNullOrWhiteSpace(e.Data))
{
lines.Add(e.Data);
}
};

process = Process.Start(startInfo);
process.Start();
}
catch
{
// when error running dotnet command, consider dotnet as not available
yield break;
}

if (process.HasExited)
{
yield break;
}

var lines = new List<string>();
process.OutputDataReceived += (_, e) =>
{
if (!string.IsNullOrWhiteSpace(e.Data))
{
lines.Add(e.Data);
}
};

process.BeginOutputReadLine();

process.WaitForExit();

var outputString = string.Join(Environment.NewLine, lines);

var matched = DotNetBasePathRegex.Match(outputString);
if (!matched.Success)
string basePath = null;
if (matched.Success)
{
yield break;
basePath = matched.Groups[1].Value.Trim();
yield return basePath;
}

var basePath = matched.Groups[1].Value.Trim();

yield return basePath; // We return the version in use at the front of the list in order to ensure FirstOrDefault always returns the version in use.

var lineSdkIndex = lines.FindIndex(line => line.Contains("SDKs installed"));

Expand Down

0 comments on commit 23fb66e

Please sign in to comment.