Beispiel #1
0
        private static async Task<int> ContinueRun(
            IPythonInterpreterFactory factory,
            Redirector output,
            bool elevate,
            params string[] cmd
        ) {
            bool isScript;
            var easyInstallPath = GetEasyInstallPath(factory, out isScript);
            if (easyInstallPath == null) {
                throw new FileNotFoundException("Cannot find setuptools ('easy_install.exe')");
            }

            var args = cmd.ToList();
            args.Insert(0, "--always-copy");
            args.Insert(0, "--always-unzip");
            if (isScript) {
                args.Insert(0, ProcessOutput.QuoteSingleArgument(easyInstallPath));
                easyInstallPath = factory.Configuration.InterpreterPath;
            }
            using (var proc = ProcessOutput.Run(
                easyInstallPath,
                args,
                factory.Configuration.PrefixPath,
                UnbufferedEnv,
                false,
                output,
                false,
                elevate
            )) {
                return await proc;
            }
        }
Beispiel #2
0
        private static ProcessOutput Run(
            IPythonInterpreterFactory factory,
            Redirector output,
            bool elevate,
            params string[] cmd
        ) {
            factory.ThrowIfNotRunnable("factory");

            IEnumerable<string> args;
            if (factory.Configuration.Version >= SupportsDashMPip) {
                args = new[] { "-m", "pip" }.Concat(cmd);
            } else {
                // Manually quote the code, since we are passing false to
                // quoteArgs below.
                args = new[] { "-c", "\"import pip; pip.main()\"" }.Concat(cmd);
            }

            return ProcessOutput.Run(
                factory.Configuration.InterpreterPath,
                args,
                factory.Configuration.PrefixPath,
                UnbufferedEnv,
                false,
                output,
                quoteArgs: false,
                elevate: elevate
            );
        }
        protected override void OnCreate() {
            base.OnCreate();

            _site = (IServiceProvider)this;

            _pyService = _site.GetPythonToolsService();

            // TODO: Get PYEnvironment added to image list
            BitmapImageMoniker = KnownMonikers.DockPanel;
            Caption = Strings.Environments;

            _service = _site.GetComponentModel().GetService<IInterpreterOptionsService>();
            
            _outputWindow = OutputWindowRedirector.GetGeneral(_site);
            Debug.Assert(_outputWindow != null);
            _statusBar = _site.GetService(typeof(SVsStatusbar)) as IVsStatusbar;
            
            var list = new ToolWindow();
            list.Site = _site;
            list.ViewCreated += List_ViewCreated;

            list.CommandBindings.Add(new CommandBinding(
                EnvironmentView.OpenInteractiveWindow,
                OpenInteractiveWindow_Executed,
                OpenInteractiveWindow_CanExecute
            ));
            list.CommandBindings.Add(new CommandBinding(
                EnvironmentView.OpenInteractiveOptions,
                OpenInteractiveOptions_Executed,
                OpenInteractiveOptions_CanExecute
            ));
            list.CommandBindings.Add(new CommandBinding(
                EnvironmentPathsExtension.StartInterpreter,
                StartInterpreter_Executed,
                StartInterpreter_CanExecute
            ));
            list.CommandBindings.Add(new CommandBinding(
                EnvironmentPathsExtension.StartWindowsInterpreter,
                StartInterpreter_Executed,
                StartInterpreter_CanExecute
            ));
            list.CommandBindings.Add(new CommandBinding(
                ApplicationCommands.Help,
                OnlineHelp_Executed,
                OnlineHelp_CanExecute
            ));
            list.CommandBindings.Add(new CommandBinding(
                ToolWindow.UnhandledException,
                UnhandledException_Executed,
                UnhandledException_CanExecute
            ));

            list.Service = _service;

            Content = list;
        }
Beispiel #4
0
        internal EnvironmentView(
            IInterpreterOptionsService service,
            IInterpreterRegistryService registry,
            IPythonInterpreterFactory factory,
            Redirector redirector
        ) {
            if (service == null) {
                throw new ArgumentNullException(nameof(service));
            }
            if (registry == null) {
                throw new ArgumentNullException(nameof(registry));
            }
            if (factory == null) {
                throw new ArgumentNullException(nameof(factory));
            }
            if (factory.Configuration == null) {
                throw new ArgumentException("factory must include a configuration");
            }

            _service = service;
            _registry = registry;
            Factory = factory;
            Configuration = Factory.Configuration;

            _withDb = factory as IPythonInterpreterFactoryWithDatabase;
            if (_withDb != null) {
                _withDb.IsCurrentChanged += Factory_IsCurrentChanged;
                IsCheckingDatabase = _withDb.IsCheckingDatabase;
                IsCurrent = _withDb.IsCurrent;
            }
            

            if (_service.IsConfigurable(Factory.Configuration.Id)) {
                IsConfigurable = true;
            }

            Description = Factory.Configuration.Description;
            IsDefault = (_service != null && _service.DefaultInterpreterId == Configuration.Id);

            PrefixPath = Factory.Configuration.PrefixPath;
            InterpreterPath = Factory.Configuration.InterpreterPath;
            WindowsInterpreterPath = Factory.Configuration.WindowsInterpreterPath;

            Extensions = new ObservableCollection<object>();
            Extensions.Add(new EnvironmentPathsExtensionProvider());
            if (IsConfigurable) {
                Extensions.Add(new ConfigurationExtensionProvider(_service, alwaysCreateNew: false));
            }

            CanBeDefault = Factory.CanBeDefault();

            Company = _registry.GetProperty(Factory.Configuration.Id, CompanyKey) as string ?? "";
            SupportUrl = _registry.GetProperty(Factory.Configuration.Id, SupportUrlKey) as string ?? "";
        }
Beispiel #5
0
 /// <summary>
 /// Creates a provider for managing packages through pip.
 /// </summary>
 /// <param name="factory">The associated interpreter.</param>
 /// <param name="index">
 /// The index URL. Defaults to https://pypi.python.org/pypi/
 /// </param>
 /// <param name="indexName">
 /// Display name of the index. Defaults to PyPI.
 /// </param>
 public PipExtensionProvider(
     IPythonInterpreterFactory factory,
     string index = null,
     string indexName = null
 ) {
     _factory = factory;
     _output = new PipRedirector(this);
     if (!string.IsNullOrEmpty(index) && Uri.TryCreate(index, UriKind.Absolute, out _index)) {
         _indexName = string.IsNullOrEmpty(indexName) ? _index.Host : indexName;
     }
     _cache = PipPackageCache.GetCache(_index, _indexName);
 }
Beispiel #6
0
 /// <summary>
 /// Installs virtualenv. If pip is not installed, the returned task will
 /// succeed but error text will be passed to the redirector.
 /// </summary>
 public static Task<bool> Install(IServiceProvider provider, IPythonInterpreterFactory factory, Redirector output = null) {
     bool elevate = provider.GetPythonToolsService().GeneralOptions.ElevatePip;
     if (factory.Configuration.Version < new Version(2, 5)) {
         if (output != null) {
             output.WriteErrorLine("Python versions earlier than 2.5 are not supported by PTVS.");
         }
         throw new OperationCanceledException();
     } else if (factory.Configuration.Version == new Version(2, 5)) {
         return Pip.Install(provider, factory, "https://go.microsoft.com/fwlink/?LinkID=317970", elevate, output);
     } else {
         return Pip.Install(provider, factory, "https://go.microsoft.com/fwlink/?LinkID=317969", elevate, output);
     }
 }
Beispiel #7
0
        internal EnvironmentView(
            IInterpreterOptionsService service,
            IPythonInterpreterFactory factory,
            Redirector redirector
        ) {
            if (service == null) {
                throw new ArgumentNullException("service");
            }
            if (factory == null) {
                throw new ArgumentNullException("factory");
            }

            _service = service;
            Factory = factory;

            _withDb = factory as IPythonInterpreterFactoryWithDatabase;
            if (_withDb != null) {
                _withDb.IsCurrentChanged += Factory_IsCurrentChanged;
                IsCheckingDatabase = _withDb.IsCheckingDatabase;
                IsCurrent = _withDb.IsCurrent;
            }

            var configurableProvider = _service != null ?
                _service.KnownProviders
                    .OfType<ConfigurablePythonInterpreterFactoryProvider>()
                    .FirstOrDefault() :
                null;

            if (configurableProvider != null && configurableProvider.IsConfigurable(factory)) {
                IsConfigurable = true;
            }

            Description = Factory.Description;
            IsDefault = (_service != null && _service.DefaultInterpreter == Factory);

            PrefixPath = Factory.Configuration.PrefixPath;
            InterpreterPath = Factory.Configuration.InterpreterPath;
            WindowsInterpreterPath = Factory.Configuration.WindowsInterpreterPath;
            LibraryPath = Factory.Configuration.LibraryPath;

            Extensions = new ObservableCollection<object>();
            Extensions.Add(new EnvironmentPathsExtensionProvider());
            if (IsConfigurable) {
                Extensions.Add(new ConfigurationExtensionProvider(configurableProvider));
            }

            CanBeDefault = Factory.CanBeDefault();
        }
 public AddVirtualEnvironmentOperation(
     PythonProjectNode project,
     string virtualEnvPath,
     IPythonInterpreterFactory baseInterpreter,
     bool create,
     bool useVEnv,
     bool installRequirements,
     Redirector output = null
 ) {
     _project = project;
     _virtualEnvPath = virtualEnvPath;
     _baseInterpreter = baseInterpreter;
     _create = create;
     _useVEnv = useVEnv;
     _installRequirements = installRequirements;
     _output = output;
 }
Beispiel #9
0
        private static async Task ContinueCreate(IServiceProvider provider, IPythonInterpreterFactory factory, string path, bool useVEnv, Redirector output) {
            path = PathUtils.TrimEndSeparator(path);
            var name = Path.GetFileName(path);
            var dir = Path.GetDirectoryName(path);

            if (output != null) {
                output.WriteLine(Strings.VirtualEnvCreating.FormatUI(path));
                if (provider.GetPythonToolsService().GeneralOptions.ShowOutputWindowForVirtualEnvCreate) {
                    output.ShowAndActivate();
                } else {
                    output.Show();
                }
            }

            // Ensure the target directory exists.
            Directory.CreateDirectory(dir);

            using (var proc = ProcessOutput.Run(
                factory.Configuration.InterpreterPath,
                new[] { "-m", useVEnv ? "venv" : "virtualenv", name },
                dir,
                UnbufferedEnv,
                false,
                output
            )) {
                var exitCode = await proc;

                if (output != null) {
                    if (exitCode == 0) {
                        output.WriteLine(Strings.VirtualEnvCreationSucceeded.FormatUI(path));
                    } else {
                        output.WriteLine(Strings.VirtualEnvCreationFailedExitCode.FormatUI(path, exitCode));
                    }
                    if (provider.GetPythonToolsService().GeneralOptions.ShowOutputWindowForVirtualEnvCreate) {
                        output.ShowAndActivate();
                    } else {
                        output.Show();
                    }
                }

                if (exitCode != 0 || !Directory.Exists(path)) {
                    throw new InvalidOperationException(Strings.VirtualEnvCreationFailed.FormatUI(path));
                }
            }
        }
Beispiel #10
0
        /// <summary>
        /// Runs the file with the provided settings.
        /// </summary>
        /// <param name="filename">Executable file to run.</param>
        /// <param name="arguments">Arguments to pass.</param>
        /// <param name="workingDirectory">Starting directory.</param>
        /// <param name="env">Environment variables to set.</param>
        /// <param name="visible">
        /// False to hide the window and redirect output to
        /// <see cref="StandardOutputLines"/> and
        /// <see cref="StandardErrorLines"/>.
        /// </param>
        /// <param name="redirector">
        /// An object to receive redirected output.
        /// </param>
        /// <param name="quoteArgs">
        /// True to ensure each argument is correctly quoted.
        /// </param>
        /// <param name="elevate">
        /// True to run the process as an administrator. See
        /// <see cref="RunElevated"/>.
        /// </param>
        /// <returns>A <see cref="ProcessOutput"/> object.</returns>
        public static ProcessOutput Run(
            string filename,
            IEnumerable<string> arguments,
            string workingDirectory,
            IEnumerable<KeyValuePair<string, string>> env,
            bool visible,
            Redirector redirector,
            bool quoteArgs = true,
            bool elevate = false,
            Encoding outputEncoding = null,
            Encoding errorEncoding = null
        ) {
            if (string.IsNullOrEmpty(filename)) {
                throw new ArgumentException("Filename required", "filename");
            }
            if (elevate) {
                return RunElevated(
                    filename,
                    arguments,
                    workingDirectory,
                    env,
                    redirector,
                    quoteArgs,
                    elevate,
                    outputEncoding,
                    errorEncoding
                );
            }

            var psi = new ProcessStartInfo(filename);
            if (quoteArgs) {
                psi.Arguments = string.Join(" ",
                    arguments.Where(a => a != null).Select(QuoteSingleArgument));
            } else {
                psi.Arguments = string.Join(" ", arguments.Where(a => a != null));
            }
            psi.WorkingDirectory = workingDirectory;
            psi.CreateNoWindow = !visible;
            psi.UseShellExecute = false;
            psi.RedirectStandardError = !visible || (redirector != null);
            psi.RedirectStandardOutput = !visible || (redirector != null);
            psi.RedirectStandardInput = !visible;
            psi.StandardOutputEncoding = outputEncoding ?? psi.StandardOutputEncoding;
            psi.StandardErrorEncoding = errorEncoding ?? outputEncoding ?? psi.StandardErrorEncoding;
            if (env != null) {
                foreach (var kv in env) {
                    psi.EnvironmentVariables[kv.Key] = kv.Value;
                }
            }

            var process = new Process { StartInfo = psi };
            return new ProcessOutput(process, redirector);
        }
Beispiel #11
0
        public static async Task InstallPip(IServiceProvider provider, IPythonInterpreterFactory factory, bool elevate, Redirector output = null) {
            factory.ThrowIfNotRunnable("factory");

            var pipDownloaderPath = PythonToolsInstallPath.GetFile("pip_downloader.py");

            if (output != null) {
                output.WriteLine(Strings.PipInstalling);
                if (provider.GetPythonToolsService().GeneralOptions.ShowOutputWindowForPackageInstallation) {
                    output.ShowAndActivate();
                } else {
                    output.Show();
                }
            }
            using (var proc = ProcessOutput.Run(
                factory.Configuration.InterpreterPath,
                new[] { pipDownloaderPath },
                factory.Configuration.PrefixPath,
                null,
                false,
                output,
                elevate: elevate
            )) {
                var exitCode = await proc;
                if (output != null) {
                    if (exitCode == 0) {
                        output.WriteLine(Strings.PipInstallSucceeded);
                    } else {
                        output.WriteLine(Strings.PipInstallFailedExitCode.FormatUI(exitCode));
                    }
                    if (provider.GetPythonToolsService().GeneralOptions.ShowOutputWindowForPackageInstallation) {
                        output.ShowAndActivate();
                    } else {
                        output.Show();
                    }
                }
            }
        }
Beispiel #12
0
        public static async Task<bool> Install(
            IServiceProvider provider,
            IPythonInterpreterFactory factory,
            IInterpreterOptionsService service,
            string package,
            Redirector output = null
        ) {
            factory.ThrowIfNotRunnable("factory");

            var condaFactory = await TryGetCondaFactoryAsync(factory, service); ;
            if (condaFactory == null) {
                throw new InvalidOperationException("Cannot find conda");
            }
            condaFactory.ThrowIfNotRunnable();

            if (output != null) {
                output.WriteLine(Strings.PackageInstalling.FormatUI(package));
                if (provider.GetPythonToolsService().GeneralOptions.ShowOutputWindowForPackageInstallation) {
                    output.ShowAndActivate();
                } else {
                    output.Show();
                }
            }

            using (var proc = ProcessOutput.Run(
                condaFactory.Configuration.InterpreterPath,
                new[] { "-m", "conda", "install", "--yes", "-n", factory.Configuration.PrefixPath, package },
                factory.Configuration.PrefixPath,
                UnbufferedEnv,
                false,
                output
            )) {
                var exitCode = await proc;
                if (output != null) {
                    if (exitCode == 0) {
                        output.WriteLine(Strings.PackageInstallSucceeded.FormatUI(package));
                    } else {
                        output.WriteLine(Strings.PackageInstallFailedExitCode.FormatUI(package, exitCode));
                    }
                    if (provider.GetPythonToolsService().GeneralOptions.ShowOutputWindowForPackageInstallation) {
                        output.ShowAndActivate();
                    } else {
                        output.Show();
                    }
                }
                return exitCode == 0;
            }
        }
Beispiel #13
0
        /// <summary>
        /// Creates a virtual environment. If virtualenv or pip are not
        /// installed then they are downloaded and installed automatically.
        /// </summary>
        public static async Task CreateAndInstallDependencies(
            IServiceProvider provider,
            IPythonInterpreterFactory factory,
            string path,
            Redirector output = null
        ) {
            factory.ThrowIfNotRunnable("factory");

            var modules = await factory.FindModulesAsync("pip", "virtualenv", "venv");
            bool hasPip = modules.Contains("pip");
            bool hasVirtualEnv = modules.Contains("virtualenv") || modules.Contains("venv");

            if (!hasVirtualEnv) {
                if (!hasPip) {
                    bool elevate = provider.GetPythonToolsService().GeneralOptions.ElevatePip;
                    await Pip.InstallPip(provider, factory, elevate, output);
                }
                if (!await Install(provider, factory, output)) {
                    throw new InvalidOperationException(Strings.VirtualEnvCreationFailed.FormatUI(path));
                }
            }

            await ContinueCreate(provider, factory, path, false, output);
        }
Beispiel #14
0
        public static async Task<bool> Uninstall(
            IServiceProvider provider,
            IPythonInterpreterFactory factory,
            string package,
            bool elevate,
            Redirector output = null
        ) {
            factory.ThrowIfNotRunnable("factory");

            if (output != null) {
                output.WriteLine(Strings.PackageUninstalling.FormatUI(package));
                if (provider.GetPythonToolsService().GeneralOptions.ShowOutputWindowForPackageInstallation) {
                    output.ShowAndActivate();
                } else {
                    output.Show();
                }
            }

            using (var proc = Run(factory, output, elevate, "uninstall", "-y", package)) {
                var exitCode = await proc;

                if (output != null) {
                    if (exitCode == 0) {
                        output.WriteLine(Strings.PackageUninstallSucceeded.FormatUI(package));
                    } else {
                        output.WriteLine(Strings.PackageUninstallFailedExitCode.FormatUI(package, exitCode));
                    }
                    if (provider.GetPythonToolsService().GeneralOptions.ShowOutputWindowForPackageInstallation) {
                        output.ShowAndActivate();
                    } else {
                        output.Show();
                    }
                }
                return exitCode == 0;
            }
        }
Beispiel #15
0
        public static async Task<bool> Install(
            IServiceProvider provider,
            IPythonInterpreterFactory factory,
            string package,
            IServiceProvider site,
            bool elevate,
            Redirector output = null
        ) {
            factory.ThrowIfNotRunnable("factory");

            if (!(await factory.FindModulesAsync("pip")).Any()) {
                if (site != null) {
                    try {
                        await QueryInstallPip(factory, site, Strings.InstallPip, elevate, output);
                    } catch (OperationCanceledException) {
                        return false;
                    }
                } else {
                    await InstallPip(provider, factory, elevate, output);
                }
            }

            if (output != null) {
                output.WriteLine(Strings.PackageInstalling.FormatUI(package));
                if (provider.GetPythonToolsService().GeneralOptions.ShowOutputWindowForPackageInstallation) {
                    output.ShowAndActivate();
                } else {
                    output.Show();
                }
            }

            using (var proc = Run(factory, output, elevate, "install", GetInsecureArg(factory, output), package)) {
                var exitCode = await proc;

                if (output != null) {
                    if (exitCode == 0) {
                        output.WriteLine(Strings.PackageInstallSucceeded.FormatUI(package));
                    } else {
                        output.WriteLine(Strings.PackageInstallFailedExitCode.FormatUI(package, exitCode));
                    }
                    if (provider.GetPythonToolsService().GeneralOptions.ShowOutputWindowForPackageInstallation) {
                        output.ShowAndActivate();
                    } else {
                        output.Show();
                    }
                }
                return exitCode == 0;
            }
        }
Beispiel #16
0
        public static async Task<bool> Install(
            IServiceProvider provider,
            IPythonInterpreterFactory factory,
            string package,
            bool elevate,
            Redirector output = null
        ) {
            factory.ThrowIfNotRunnable("factory");

            if (!(await factory.FindModulesAsync("pip")).Any()) {
                await InstallPip(provider, factory, elevate, output);
            }
            using (var proc = Run(factory, output, elevate, "install", GetInsecureArg(factory, output), package)) {
                await proc;
                return proc.ExitCode == 0;
            }
        }
Beispiel #17
0
        public static async Task QueryInstallPip(
            IPythonInterpreterFactory factory,
            IServiceProvider site,
            string message,
            bool elevate,
            Redirector output = null
        ) {
            factory.ThrowIfNotRunnable("factory");

            if (Microsoft.VisualStudio.Shell.VsShellUtilities.ShowMessageBox(
                site,
                message,
                null,
                OLEMSGICON.OLEMSGICON_QUERY,
                OLEMSGBUTTON.OLEMSGBUTTON_OKCANCEL,
                OLEMSGDEFBUTTON.OLEMSGDEFBUTTON_FIRST
            ) == 2) {
                throw new OperationCanceledException();
            }

            await InstallPip(site, factory, elevate, output);
        }
Beispiel #18
0
        /// <summary>
        /// Runs the file with the provided settings as a user with
        /// administrative permissions. The window is always hidden and output
        /// is provided to the redirector when the process terminates.
        /// </summary>
        /// <param name="filename">Executable file to run.</param>
        /// <param name="arguments">Arguments to pass.</param>
        /// <param name="workingDirectory">Starting directory.</param>
        /// <param name="redirector">
        /// An object to receive redirected output.
        /// </param>
        /// <param name="quoteArgs"></param>
        /// <returns>A <see cref="ProcessOutput"/> object.</returns>
        public static ProcessOutput RunElevated(
            string filename,
            IEnumerable <string> arguments,
            string workingDirectory,
            IEnumerable <KeyValuePair <string, string> > env,
            Redirector redirector,
            bool quoteArgs          = true,
            bool elevate            = true,
            Encoding outputEncoding = null,
            Encoding errorEncoding  = null
            )
        {
            var psi = new ProcessStartInfo(PythonToolsInstallPath.GetFile("Microsoft.PythonTools.RunElevated.exe", typeof(ProcessOutput).Assembly));

            psi.CreateNoWindow  = true;
            psi.WindowStyle     = ProcessWindowStyle.Hidden;
            psi.UseShellExecute = true;
            psi.Verb            = elevate ? "runas" : null;

            var utf8 = new UTF8Encoding(false);
            // Send args and env as base64 to avoid newline issues
            string args;

            if (quoteArgs)
            {
                args = string.Join("|", arguments
                                   .Where(a => a != null)
                                   .Select(a => Convert.ToBase64String(utf8.GetBytes(QuoteSingleArgument(a))))
                                   );
            }
            else
            {
                args = string.Join("|", arguments
                                   .Where(a => a != null)
                                   .Select(a => Convert.ToBase64String(utf8.GetBytes(a)))
                                   );
            }

            var fullEnv = env != null?
                          string.Join("|", env.Select(kv => kv.Key + "=" + Convert.ToBase64String(utf8.GetBytes(kv.Value)))) :
                              "";

            TcpListener      listener   = null;
            Task <TcpClient> clientTask = null;

            for (int retries = 10; retries >= 0; --retries)
            {
                int port = GetFreePort();
                listener      = new TcpListener(IPAddress.Loopback, port);
                psi.Arguments = port.ToString();
                try {
                    listener.Start();
                } catch (SocketException) {
                    if (retries == 0)
                    {
                        throw;
                    }
                    continue;
                }
                try {
                    clientTask = listener.AcceptTcpClientAsync();
                } catch (SocketException) {
                    listener.Stop();
                    if (retries == 0)
                    {
                        throw;
                    }
                    clientTask = null;
                }
            }

            if (clientTask == null)
            {
                throw new InvalidOperationException(Strings.UnableToElevate);
            }

            var process = new Process();

            clientTask.ContinueWith(t => {
                listener.Stop();
                TcpClient client;
                try {
                    client = t.Result;
                } catch (AggregateException ae) {
                    try {
                        process.Kill();
                    } catch (InvalidOperationException) {
                    } catch (Win32Exception) {
                    }

                    if (redirector != null)
                    {
                        foreach (var ex in ae.InnerExceptions.DefaultIfEmpty(ae))
                        {
                            using (var reader = new StringReader(ex.ToString())) {
                                for (var line = reader.ReadLine(); line != null; line = reader.ReadLine())
                                {
                                    redirector.WriteErrorLine(line);
                                }
                            }
                        }
                    }
                    return;
                }
                using (var writer = new StreamWriter(client.GetStream(), utf8, 4096, true)) {
                    writer.WriteLine(filename);
                    writer.WriteLine(args);
                    writer.WriteLine(workingDirectory);
                    writer.WriteLine(fullEnv);
                    writer.WriteLine(outputEncoding?.WebName ?? "");
                    writer.WriteLine(errorEncoding?.WebName ?? "");
                }

                if (redirector != null)
                {
                    var reader = new StreamReader(client.GetStream(), utf8, false, 4096, true);
                    Task.Run(() => {
                        try {
                            for (var line = reader.ReadLine(); line != null; line = reader.ReadLine())
                            {
                                if (line.StartsWith("OUT:"))
                                {
                                    redirector.WriteLine(line.Substring(4));
                                }
                                else if (line.StartsWith("ERR:"))
                                {
                                    redirector.WriteErrorLine(line.Substring(4));
                                }
                                else
                                {
                                    redirector.WriteLine(line);
                                }
                            }
                        } catch (IOException) {
                        } catch (ObjectDisposedException) {
                        }
                    });
                }
            });

            process.StartInfo = psi;

            return(new ProcessOutput(process, redirector));
        }
Beispiel #19
0
        private ProcessOutput(Process process, Redirector redirector)
        {
            _arguments  = QuoteSingleArgument(process.StartInfo.FileName) + " " + process.StartInfo.Arguments;
            _redirector = redirector;
            if (_redirector == null)
            {
                _output     = new List <string>();
                _error      = new List <string>();
                _redirector = new ListRedirector(_output, _error);
            }

            _process = process;
            if (_process.StartInfo.RedirectStandardOutput)
            {
                _process.OutputDataReceived += OnOutputDataReceived;
            }
            if (_process.StartInfo.RedirectStandardError)
            {
                _process.ErrorDataReceived += OnErrorDataReceived;
            }

            if (!_process.StartInfo.RedirectStandardOutput && !_process.StartInfo.RedirectStandardError)
            {
                // If we are receiving output events, we signal that the process
                // has exited when one of them receives null. Otherwise, we have
                // to listen for the Exited event.
                // If we just listen for the Exited event, we may receive it
                // before all the output has arrived.
                _process.Exited += OnExited;
            }
            _process.EnableRaisingEvents = true;

            try {
                _process.Start();
            } catch (Exception ex) when(!ex.IsCriticalException())
            {
                foreach (var line in SplitLines(ex.ToString()))
                {
                    _redirector.WriteErrorLine(line);
                }
                _process = null;
            }

            if (_process != null)
            {
                if (_process.StartInfo.RedirectStandardOutput)
                {
                    _process.BeginOutputReadLine();
                }
                if (_process.StartInfo.RedirectStandardError)
                {
                    _process.BeginErrorReadLine();
                }

                if (_process.StartInfo.RedirectStandardInput)
                {
                    // Close standard input so that we don't get stuck trying to read input from the user.
                    try {
                        _process.StandardInput.Close();
                    } catch (InvalidOperationException) {
                        // StandardInput not available
                    }
                }
            }
        }
Beispiel #20
0
        /// <summary>
        /// Runs the file with the provided settings.
        /// </summary>
        /// <param name="filename">Executable file to run.</param>
        /// <param name="arguments">Arguments to pass.</param>
        /// <param name="workingDirectory">Starting directory.</param>
        /// <param name="env">Environment variables to set.</param>
        /// <param name="visible">
        /// False to hide the window and redirect output to
        /// <see cref="StandardOutputLines"/> and
        /// <see cref="StandardErrorLines"/>.
        /// </param>
        /// <param name="redirector">
        /// An object to receive redirected output.
        /// </param>
        /// <param name="quoteArgs">
        /// True to ensure each argument is correctly quoted.
        /// </param>
        /// <param name="elevate">
        /// True to run the process as an administrator. See
        /// <see cref="RunElevated"/>.
        /// </param>
        /// <returns>A <see cref="ProcessOutput"/> object.</returns>
        public static ProcessOutput Run(
            string filename,
            IEnumerable <string> arguments,
            string workingDirectory,
            IEnumerable <KeyValuePair <string, string> > env,
            bool visible,
            Redirector redirector,
            bool quoteArgs          = true,
            bool elevate            = false,
            Encoding outputEncoding = null,
            Encoding errorEncoding  = null
            )
        {
            if (string.IsNullOrEmpty(filename))
            {
                throw new ArgumentException("Filename required", "filename");
            }
            if (elevate)
            {
                return(RunElevated(
                           filename,
                           arguments,
                           workingDirectory,
                           env,
                           redirector,
                           quoteArgs,
                           elevate,
                           outputEncoding,
                           errorEncoding
                           ));
            }

            var psi = new ProcessStartInfo(filename);

            if (quoteArgs)
            {
                psi.Arguments = string.Join(" ",
                                            arguments.Where(a => a != null).Select(QuoteSingleArgument));
            }
            else
            {
                psi.Arguments = string.Join(" ", arguments.Where(a => a != null));
            }
            psi.WorkingDirectory       = workingDirectory;
            psi.CreateNoWindow         = !visible;
            psi.UseShellExecute        = false;
            psi.RedirectStandardError  = !visible || (redirector != null);
            psi.RedirectStandardOutput = !visible || (redirector != null);
            psi.RedirectStandardInput  = !visible;
            psi.StandardOutputEncoding = outputEncoding ?? psi.StandardOutputEncoding;
            psi.StandardErrorEncoding  = errorEncoding ?? outputEncoding ?? psi.StandardErrorEncoding;
            if (env != null)
            {
                foreach (var kv in env)
                {
                    psi.EnvironmentVariables[kv.Key] = kv.Value;
                }
            }

            var process = new Process {
                StartInfo = psi
            };

            return(new ProcessOutput(process, redirector));
        }
Beispiel #21
0
        /// <summary>
        /// Runs the file with the provided settings as a user with
        /// administrative permissions. The window is always hidden and output
        /// is provided to the redirector when the process terminates.
        /// </summary>
        /// <param name="filename">Executable file to run.</param>
        /// <param name="arguments">Arguments to pass.</param>
        /// <param name="workingDirectory">Starting directory.</param>
        /// <param name="redirector">
        /// An object to receive redirected output.
        /// </param>
        /// <param name="quoteArgs"></param>
        /// <returns>A <see cref="ProcessOutput"/> object.</returns>
        public static ProcessOutput RunElevated(
            string filename,
            IEnumerable<string> arguments,
            string workingDirectory,
            Redirector redirector,
            bool quoteArgs = true,
            Encoding outputEncoding = null,
            Encoding errorEncoding = null
        ) {
            var outFile = Path.GetTempFileName();
            var errFile = Path.GetTempFileName();
            var psi = new ProcessStartInfo("cmd.exe");
            psi.CreateNoWindow = true;
            psi.WindowStyle = ProcessWindowStyle.Hidden;
            psi.UseShellExecute = true;
            psi.Verb = "runas";

            string args;
            if (quoteArgs) {
                args = string.Join(" ", arguments.Where(a => a != null).Select(QuoteSingleArgument));
            } else {
                args = string.Join(" ", arguments.Where(a => a != null));
            }
            psi.Arguments = string.Format("/S /C \"{0} {1} >>{2} 2>>{3}\"",
                QuoteSingleArgument(filename),
                args,
                QuoteSingleArgument(outFile),
                QuoteSingleArgument(errFile)
            );
            psi.WorkingDirectory = workingDirectory;
            psi.CreateNoWindow = true;
            psi.UseShellExecute = true;

            var process = new Process();
            process.StartInfo = psi;
            var result = new ProcessOutput(process, redirector);
            if (redirector != null) {
                result.Exited += (s, e) => {
                    try {
                        try {
                            var lines = File.ReadAllLines(outFile, outputEncoding ?? Encoding.Default);
                            foreach (var line in lines) {
                                redirector.WriteLine(line);
                            }
                        } catch (Exception ex) when(!ex.IsCriticalException()) {
                            redirector.WriteErrorLine("Failed to obtain standard output from elevated process.");
#if DEBUG
                            foreach (var line in SplitLines(ex.ToString())) {
                                redirector.WriteErrorLine(line);
                            }
#else
                            Trace.TraceError("Failed to obtain standard output from elevated process.");
                            Trace.TraceError(ex.ToString());
#endif
                        }
                        try {
                            var lines = File.ReadAllLines(errFile, errorEncoding ?? outputEncoding ?? Encoding.Default);
                            foreach (var line in lines) {
                                redirector.WriteErrorLine(line);
                            }
                        } catch (Exception ex) when(!ex.IsCriticalException()) {
                            redirector.WriteErrorLine("Failed to obtain standard error from elevated process.");
#if DEBUG
                            foreach (var line in SplitLines(ex.ToString())) {
                                redirector.WriteErrorLine(line);
                            }
#else
                            Trace.TraceError("Failed to obtain standard error from elevated process.");
                            Trace.TraceError(ex.ToString());
#endif
                        }
                    } finally {
                        try {
                            File.Delete(outFile);
                        } catch { }
                        try {
                            File.Delete(errFile);
                        } catch { }
                    }
                };
            }
            return result;
        }
Beispiel #22
0
        internal EnvironmentView(
            IInterpreterOptionsService service,
            IInterpreterRegistryService registry,
            IPythonInterpreterFactory factory,
            Redirector redirector
            )
        {
            if (service == null) {
                throw new ArgumentNullException(nameof(service));
            }
            if (registry == null) {
                throw new ArgumentNullException(nameof(registry));
            }
            if (factory == null) {
                throw new ArgumentNullException(nameof(factory));
            }

            _service = service;
            _registry = registry;
            Factory = factory;

            _withDb = factory as IPythonInterpreterFactoryWithDatabase;
            if (_withDb != null) {
                _withDb.IsCurrentChanged += Factory_IsCurrentChanged;
                IsCheckingDatabase = _withDb.IsCheckingDatabase;
                IsCurrent = _withDb.IsCurrent;
            }

            if (_service.IsConfigurable(factory.Configuration.Id)) {
                IsConfigurable = true;
            }

            Description = Factory.Configuration.FullDescription;
            IsDefault = (_service != null && _service.DefaultInterpreter == Factory);

            PrefixPath = Factory.Configuration.PrefixPath;
            InterpreterPath = Factory.Configuration.InterpreterPath;
            WindowsInterpreterPath = Factory.Configuration.WindowsInterpreterPath;
            LibraryPath = Factory.Configuration.LibraryPath;

            Extensions = new ObservableCollection<object>();
            Extensions.Add(new EnvironmentPathsExtensionProvider());
            if (IsConfigurable) {
                Extensions.Add(new ConfigurationExtensionProvider(_service));
            }

            CanBeDefault = Factory.CanBeDefault();

            Vendor = _registry.GetProperty(Factory.Configuration.Id, "Vendor") as string;
            SupportUrl = _registry.GetProperty(Factory.Configuration.Id, "SupportUrl") as string;
        }
Beispiel #23
0
        /// <summary>
        /// Runs the file with the provided settings as a user with
        /// administrative permissions. The window is always hidden and output
        /// is provided to the redirector when the process terminates.
        /// </summary>
        /// <param name="filename">Executable file to run.</param>
        /// <param name="arguments">Arguments to pass.</param>
        /// <param name="workingDirectory">Starting directory.</param>
        /// <param name="redirector">
        /// An object to receive redirected output.
        /// </param>
        /// <param name="quoteArgs"></param>
        /// <returns>A <see cref="ProcessOutput"/> object.</returns>
        public static ProcessOutput RunElevated(
            string filename,
            IEnumerable<string> arguments,
            string workingDirectory,
            IEnumerable<KeyValuePair<string, string>> env,
            Redirector redirector,
            bool quoteArgs = true,
            bool elevate = true,
            Encoding outputEncoding = null,
            Encoding errorEncoding = null
        ) {
            var psi = new ProcessStartInfo(PythonToolsInstallPath.GetFile("Microsoft.PythonTools.RunElevated.exe", typeof(ProcessOutput).Assembly));
            psi.CreateNoWindow = true;
            psi.WindowStyle = ProcessWindowStyle.Hidden;
            psi.UseShellExecute = true;
            psi.Verb = elevate ? "runas" : null;

            var utf8 = new UTF8Encoding(false);
            // Send args and env as base64 to avoid newline issues
            string args;
            if (quoteArgs) {
                args = string.Join("|", arguments
                    .Where(a => a != null)
                    .Select(a => Convert.ToBase64String(utf8.GetBytes(QuoteSingleArgument(a))))
                );
            } else {
                args = string.Join("|", arguments
                    .Where(a => a != null)
                    .Select(a => Convert.ToBase64String(utf8.GetBytes(a)))
                );
            }

            var fullEnv = env != null ?
                string.Join("|", env.Select(kv => kv.Key + "=" + Convert.ToBase64String(utf8.GetBytes(kv.Value)))) :
                "";

            TcpListener listener = null;
            Task<TcpClient> clientTask = null;

            for (int retries = 10; retries >= 0; --retries) {
                int port = GetFreePort();
                listener = new TcpListener(IPAddress.Loopback, port);
                psi.Arguments = port.ToString();
                try {
                    listener.Start();
                } catch (SocketException) {
                    if (retries == 0) {
                        throw;
                    }
                    continue;
                }
                try {
                    clientTask = listener.AcceptTcpClientAsync();
                } catch (SocketException) {
                    listener.Stop();
                    if (retries == 0) {
                        throw;
                    }
                    clientTask = null;
                }
            }

            if (clientTask == null) {
                throw new InvalidOperationException(Strings.UnableToElevate);
            }

            var process = new Process();

            clientTask.ContinueWith(t => {
                listener.Stop();
                TcpClient client;
                try {
                    client = t.Result;
                } catch (AggregateException ae) {
                    try {
                        process.Kill();
                    } catch (InvalidOperationException) {
                    } catch (Win32Exception) {
                    }

                    if (redirector != null) {
                        foreach (var ex in ae.InnerExceptions.DefaultIfEmpty(ae)) {
                            using (var reader = new StringReader(ex.ToString())) {
                                for (var line = reader.ReadLine(); line != null; line = reader.ReadLine()) {
                                    redirector.WriteErrorLine(line);
                                }
                            }
                        }
                    }
                    return;
                }
                using (var writer = new StreamWriter(client.GetStream(), utf8, 4096, true)) {
                    writer.WriteLine(filename);
                    writer.WriteLine(args);
                    writer.WriteLine(workingDirectory);
                    writer.WriteLine(fullEnv);
                    writer.WriteLine(outputEncoding?.WebName ?? "");
                    writer.WriteLine(errorEncoding?.WebName ?? "");
                }

                if (redirector != null) {
                    var reader = new StreamReader(client.GetStream(), utf8, false, 4096, true);
                    Task.Run(() => {
                        try {
                            for (var line = reader.ReadLine(); line != null; line = reader.ReadLine()) {
                                if (line.StartsWith("OUT:")) {
                                    redirector.WriteLine(line.Substring(4));
                                } else if (line.StartsWith("ERR:")) {
                                    redirector.WriteErrorLine(line.Substring(4));
                                } else {
                                    redirector.WriteLine(line);
                                }
                            }
                        } catch (IOException) {
                        } catch (ObjectDisposedException) {
                        }
                    });
                }
            });

            process.StartInfo = psi;

            return new ProcessOutput(process, redirector);
        }
Beispiel #24
0
        public static async Task Install(
            IPythonInterpreterFactory factory,
            string package,
            bool elevate,
            Redirector output = null
        ) {
            factory.ThrowIfNotRunnable("factory");

            await ContinueRun(factory, output, elevate, package);
        }
Beispiel #25
0
        private ProcessOutput(Process process, Redirector redirector) {
            _arguments = QuoteSingleArgument(process.StartInfo.FileName) + " " + process.StartInfo.Arguments;
            _redirector = redirector;
            if (_redirector == null) {
                _output = new List<string>();
                _error = new List<string>();
                _redirector = new ListRedirector(_output, _error);
            }

            _process = process;
            if (_process.StartInfo.RedirectStandardOutput) {
                _process.OutputDataReceived += OnOutputDataReceived;
            }
            if (_process.StartInfo.RedirectStandardError) {
                _process.ErrorDataReceived += OnErrorDataReceived;
            }

            if (!_process.StartInfo.RedirectStandardOutput && !_process.StartInfo.RedirectStandardError) {
                // If we are receiving output events, we signal that the process
                // has exited when one of them receives null. Otherwise, we have
                // to listen for the Exited event.
                // If we just listen for the Exited event, we may receive it
                // before all the output has arrived.
                _process.Exited += OnExited;
            }
            _process.EnableRaisingEvents = true;

            try {
                _process.Start();
            } catch (Exception ex) when (!ex.IsCriticalException()) {
                foreach (var line in SplitLines(ex.ToString())) {
                    _redirector.WriteErrorLine(line);
                }
                _process = null;
            }

            if (_process != null) {
                if (_process.StartInfo.RedirectStandardOutput) {
                    _process.BeginOutputReadLine();
                }
                if (_process.StartInfo.RedirectStandardError) {
                    _process.BeginErrorReadLine();
                }

                if (_process.StartInfo.RedirectStandardInput) {
                    // Close standard input so that we don't get stuck trying to read input from the user.
                    try {
                        _process.StandardInput.Close();
                    } catch (InvalidOperationException) {
                        // StandardInput not available
                    }
                }
            }
        }
Beispiel #26
0
        public static async Task<bool> Install(
            IServiceProvider provider,
            IPythonInterpreterFactory factory,
            string package,
            IServiceProvider site,
            bool elevate,
            Redirector output = null
        ) {
            factory.ThrowIfNotRunnable("factory");

            bool isScript;
            if (site != null && GetEasyInstallPath(factory, out isScript) == null) {
                await Pip.QueryInstallPip(factory, site, Strings.InstallEasyInstall, elevate, output);
            }

            if (output != null) {
                output.WriteLine(Strings.PackageInstalling.FormatUI(package));
                if (provider.GetPythonToolsService().GeneralOptions.ShowOutputWindowForPackageInstallation) {
                    output.ShowAndActivate();
                } else {
                    output.Show();
                }
            }

            var exitCode = await ContinueRun(factory, output, elevate, package);

            if (output != null) {
                if (exitCode == 0) {
                    output.WriteLine(Strings.PackageInstallSucceeded.FormatUI(package));
                } else {
                    output.WriteLine(Strings.PackageInstallFailedExitCode.FormatUI(package, exitCode));
                }
                if (provider.GetPythonToolsService().GeneralOptions.ShowOutputWindowForPackageInstallation) {
                    output.ShowAndActivate();
                } else {
                    output.Show();
                }
            }
            return exitCode == 0;
        }
Beispiel #27
0
 public VsPackageManagerUI(IServiceProvider provider, bool alwaysElevate = false) {
     _site = provider;
     _outputWindow = OutputWindowRedirector.GetGeneral(provider);
     _options = provider.GetPythonToolsService().GeneralOptions;
     _alwaysElevate = alwaysElevate;
 }
Beispiel #28
0
 /// <summary>
 /// Creates a virtual environment using venv. If venv is not available,
 /// the task will succeed but error text will be passed to the
 /// redirector.
 /// </summary>
 public static Task CreateWithVEnv(IServiceProvider provider, IPythonInterpreterFactory factory, string path, Redirector output = null) {
     factory.ThrowIfNotRunnable();
     return ContinueCreate(provider, factory, path, true, output);
 }
Beispiel #29
0
 private static string GetInsecureArg(
     IPythonInterpreterFactory factory,
     Redirector output = null
 ) {
     if (!IsSecureInstall(factory)) {
         // Python 2.5 does not include ssl, and so the --insecure
         // option is required to use pip.
         if (output != null) {
             output.WriteErrorLine("Using '--insecure' option for Python 2.5.");
         }
         return "--insecure";
     }
     return null;
 }
Beispiel #30
0
        protected override void OnCreate() {
            base.OnCreate();

            _site = (IServiceProvider)this;

            _pyService = _site.GetPythonToolsService();

            // TODO: Get PYEnvironment added to image list
            BitmapImageMoniker = KnownMonikers.DockPanel;
            Caption = Strings.Environments;

            _outputWindow = OutputWindowRedirector.GetGeneral(_site);
            Debug.Assert(_outputWindow != null);
            _statusBar = _site.GetService(typeof(SVsStatusbar)) as IVsStatusbar;
            
            var list = new ToolWindow();
            list.Site = _site;
            try {
                list.TelemetryLogger = _site.GetPythonToolsService().Logger;
            } catch (Exception ex) {
                Debug.Fail(ex.ToUnhandledExceptionMessage(GetType()));
            }
            list.ViewCreated += List_ViewCreated;

            list.CommandBindings.Add(new CommandBinding(
                EnvironmentView.OpenInteractiveWindow,
                OpenInteractiveWindow_Executed,
                OpenInteractiveWindow_CanExecute
            ));
            list.CommandBindings.Add(new CommandBinding(
                EnvironmentView.OpenInteractiveScripts,
                OpenInteractiveScripts_Executed,
                OpenInteractiveScripts_CanExecute
            ));
            list.CommandBindings.Add(new CommandBinding(
                EnvironmentPathsExtension.StartInterpreter,
                StartInterpreter_Executed,
                StartInterpreter_CanExecute
            ));
            list.CommandBindings.Add(new CommandBinding(
                EnvironmentPathsExtension.StartWindowsInterpreter,
                StartInterpreter_Executed,
                StartInterpreter_CanExecute
            ));
            list.CommandBindings.Add(new CommandBinding(
                ApplicationCommands.Help,
                OnlineHelp_Executed,
                OnlineHelp_CanExecute
            ));
            list.CommandBindings.Add(new CommandBinding(
                ToolWindow.UnhandledException,
                UnhandledException_Executed,
                UnhandledException_CanExecute
            ));
            list.CommandBindings.Add(new CommandBinding(
                EnvironmentView.OpenInPowerShell,
                OpenInPowerShell_Executed,
                OpenInPowerShell_CanExecute
            ));
            list.CommandBindings.Add(new CommandBinding(
                EnvironmentView.OpenInCommandPrompt,
                OpenInCommandPrompt_Executed,
                OpenInCommandPrompt_CanExecute
            ));
            list.CommandBindings.Add(new CommandBinding(
                EnvironmentView.EnableIPythonInteractive,
                EnableIPythonInteractive_Executed,
                EnableIPythonInteractive_CanExecute
            ));
            list.CommandBindings.Add(new CommandBinding(
                EnvironmentView.DisableIPythonInteractive,
                DisableIPythonInteractive_Executed,
                DisableIPythonInteractive_CanExecute
            ));
            list.CommandBindings.Add(new CommandBinding(
                EnvironmentPathsExtension.OpenInBrowser,
                OpenInBrowser_Executed,
                OpenInBrowser_CanExecute
            ));

            Content = list;
        }