/// <inheritdoc/> public override int ExecuteCommand(string commandText, int timeout, out string commandOutput, out string errorMessage) { using (var cancellationTokenSource = new CancellationTokenSource()) { Task <ProcessResult> task = LocalProcessAsyncRunner.ExecuteProcessAsync(WSLCommandLine.GetExecStartInfo(this.Name, commandText), cancellationTokenSource.Token); #pragma warning disable VSTHRD002 // Avoid problematic synchronous waits if (!task.Wait(timeout)) { cancellationTokenSource.Cancel(); throw new TimeoutException(); } ProcessResult result = task.Result; #pragma warning restore VSTHRD002 // Avoid problematic synchronous waits commandOutput = string.Join("\n", result.StdOut); errorMessage = string.Join("\n", result.StdErr); return(result.ExitCode); } }
public static IEnumerable <string> GetInstalledDistros() { HashSet <string> distributions = new HashSet <string>(StringComparer.OrdinalIgnoreCase); ThreadHelper.JoinableTaskFactory.Run(StringResources.WaitingOp_EnumeratingWSLDistros, async(progress, cancellationToken) => { ProcessStartInfo startInfo = GetWSLStartInfo("-l -v", Encoding.Unicode); ProcessResult processResult = await LocalProcessAsyncRunner.ExecuteProcessAsync(startInfo, cancellationToken); if (processResult.ExitCode != 0) { const int NoDistrosExitCode = -1; if (processResult.ExitCode == NoDistrosExitCode) { // Older versions of wsl don't like the '-v' and will also fail with -1 for that reason. Check if this is why we are seeing the failure ProcessResult retryResult = await LocalProcessAsyncRunner.ExecuteProcessAsync(GetWSLStartInfo("-l", Encoding.Unicode), cancellationToken); // If the exit code is still NoDistros then they really don't have any distros if (retryResult.ExitCode == NoDistrosExitCode) { throw new WSLException(StringResources.Error_WSLNoDistros); } // For any other code, they don't have WSL 2 installed. else { throw new WSLException(StringResources.WSL_V2Required); } } else { if (processResult.StdErr.Count > 0) { VsOutputWindowWrapper.WriteLine(StringResources.Error_WSLExecErrorOut_Args2.FormatCurrentCultureWithArgs(startInfo.FileName, startInfo.Arguments)); foreach (string line in processResult.StdErr) { VsOutputWindowWrapper.WriteLine("\t" + line); } } throw new WSLException(StringResources.Error_WSLEnumDistrosFailed_Args1.FormatCurrentCultureWithArgs(processResult.ExitCode)); } } // Parse the installed distributions /* Ouput looks like: * NAME STATE VERSION * Ubuntu Stopped 2 * docker-desktop-data Running 2 * docker-desktop Running 2 */ Regex distributionRegex = new Regex(@"^\*?\s+(?<name>\S+)\s"); foreach (string line in processResult.StdOut.Skip(1)) { Match match = distributionRegex.Match(line); if (match.Success) { string distroName = match.Groups["name"].Value; if (distroName.StartsWith("docker-desktop", StringComparison.OrdinalIgnoreCase)) { continue; } distributions.Add(distroName); } } }); if (distributions.Count == 0) { throw new WSLException(StringResources.Error_WSLNoDistros); } return(distributions); }