예제 #1
0
        /// <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);
            }
        }
예제 #2
0
        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);
        }