protected override void OnCreate() { base.OnCreate(); _site = (IServiceProvider)this; _pyService = _site.GetPythonToolsService(); #if DEV14_OR_LATER // TODO: Get PYEnvironment added to image list BitmapImageMoniker = KnownMonikers.DockPanel; #else BitmapResourceID = PythonConstants.ResourceIdForReplImages; BitmapIndex = 0; #endif Caption = SR.GetString(SR.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.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; }
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 ); }
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; } }
internal static async Task<IEnumerable<string>> ExecuteNpmCommandAsync( Redirector redirector, string pathToNpm, string executionDirectory, string[] arguments, ManualResetEvent cancellationResetEvent) { IEnumerable<string> standardOutputLines = null; using (var process = ProcessOutput.Run( pathToNpm, arguments, executionDirectory, null, false, redirector, quoteArgs: false, outputEncoding: Encoding.UTF8 // npm uses UTF-8 regardless of locale if its output is redirected )) { var whnd = process.WaitHandle; if (whnd == null) { // Process failed to start, and any exception message has // already been sent through the redirector if (redirector != null) { redirector.WriteErrorLine(Resources.ErrCannotStartNpm); } } else { var handles = cancellationResetEvent != null ? new[] { whnd, cancellationResetEvent } : new[] { whnd }; var i = await Task.Run(() => WaitHandle.WaitAny(handles)); if (i == 0) { Debug.Assert(process.ExitCode.HasValue, "npm process has not really exited"); process.Wait(); if (process.StandardOutputLines != null) { standardOutputLines = process.StandardOutputLines.ToList(); } if (redirector != null) { redirector.WriteLine(string.Format( "\r\n===={0}====\r\n\r\n", string.Format(Resources.NpmCommandCompletedWithExitCode, process.ExitCode ?? -1) )); } } else { process.Kill(); if (redirector != null) { redirector.WriteErrorLine(string.Format( "\r\n===={0}====\r\n\r\n", Resources.NpmCommandCancelled)); } if (cancellationResetEvent != null) { cancellationResetEvent.Reset(); } throw new OperationCanceledException(); } } } return standardOutputLines; }
public Task<bool> AcquireTypings(IEnumerable<string> packages, Redirector redirector) { return typingsToolGlobalWorkSemaphore.WaitAsync().ContinueWith(async _ => { try { return await DownloadTypingsForPackages(packages, redirector) && await DownloadTypingsForProject(redirector); } finally { typingsToolGlobalWorkSemaphore.Release(); } }).Unwrap(); }
public Task<bool> AcquireTypings(IEnumerable<string> packages, Redirector redirector) { return typingsToolGlobalWorkSemaphore.WaitAsync().ContinueWith(async _ => { var typingsToAquire = GetNewTypingsToAcquire(packages); var success = await DownloadTypings(typingsToAquire, redirector); if (success) { _acquiredTypingsPackageNames.Value.UnionWith(typingsToAquire); } typingsToolGlobalWorkSemaphore.Release(); return success; }).Unwrap(); }
private async Task<bool> DownloadTypingsForPackages(IEnumerable<string> packages, Redirector redirector) { var typingsToAquire = GetNewTypingsToAcquire(packages); if (!typingsToAquire.Any()) { return true; } var success = await ExecuteTypingsTool(GetTypingsToolInstallArguments(packages), redirector); if (success) { _acquiredTypingsPackageNames.Value.UnionWith(typingsToAquire); } return success; }
/// <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); } }
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; }
private static async Task ContinueCreate(IServiceProvider provider, IPythonInterpreterFactory factory, string path, bool useVEnv, Redirector output) { path = CommonUtils.TrimEndSeparator(path); var name = Path.GetFileName(path); var dir = Path.GetDirectoryName(path); if (output != null) { output.WriteLine(SR.GetString(SR.VirtualEnvCreating, 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(SR.GetString(SR.VirtualEnvCreationSucceeded, path)); } else { output.WriteLine(SR.GetString(SR.VirtualEnvCreationFailedExitCode, path, exitCode)); } if (provider.GetPythonToolsService().GeneralOptions.ShowOutputWindowForVirtualEnvCreate) { output.ShowAndActivate(); } else { output.Show(); } } if (exitCode != 0 || !Directory.Exists(path)) { throw new InvalidOperationException(SR.GetString(SR.VirtualEnvCreationFailed, path)); } } }
private async Task<bool> DownloadTypingsForProject(Redirector redirector) { if (!File.Exists(Path.Combine(_pathToRootProjectDirectory, "typings.json"))) { return true; } return await ExecuteTypingsTool(new string[] { }, redirector); }
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(SR.GetString(SR.PackageUninstalling, 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(SR.GetString(SR.PackageUninstallSucceeded, package)); } else { output.WriteLine(SR.GetString(SR.PackageUninstallFailedExitCode, package, exitCode)); } if (provider.GetPythonToolsService().GeneralOptions.ShowOutputWindowForPackageInstallation) { output.ShowAndActivate(); } else { output.Show(); } } return exitCode == 0; } }
private async Task<string> EnsureTypingsToolInstalled(Redirector redirector) { if (File.Exists(TypingsToolPath)) { return TypingsToolPath; } if (_didTryToInstallTypingsTool) { return null; } if (!await InstallTypingsTool()) { redirector?.WriteErrorLine(Resources.TypingsToolInstallFailed); return null; } return await EnsureTypingsToolInstalled(redirector); }
/// <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, redirector, quoteArgs, 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.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)); }
/// <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(SR.GetString(SR.VirtualEnvCreationFailed, path)); } } await ContinueCreate(provider, factory, path, false, output); }
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>(); } _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) { if (IsCriticalException(ex)) { throw; } if (_redirector != null) { foreach (var line in SplitLines(ex.ToString())) { _redirector.WriteErrorLine(line); } } else if (_error != null) { _error.AddRange(SplitLines(ex.ToString())); } _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 } } } }
/// <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, redirector, quoteArgs, 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); }
/// <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") { WindowStyle = ProcessWindowStyle.Hidden, Verb = "runas", CreateNoWindow = true, UseShellExecute = true, Arguments = string.Format(@"/S /C pushd {0} & ""{1} {2} >>{3} 2>>{4}""", QuoteSingleArgument(workingDirectory), QuoteSingleArgument(filename), GetArguments(arguments, quoteArgs), QuoteSingleArgument(outFile), QuoteSingleArgument(errFile)) }; 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) { if (IsCriticalException(ex)) { throw; } 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) { if (IsCriticalException(ex)) { throw; } 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); }
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, SR.GetString(SR.InstallEasyInstall), elevate, output); } if (output != null) { output.WriteLine(SR.GetString(SR.PackageInstalling, 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(SR.GetString(SR.PackageInstallSucceeded, package)); } else { output.WriteLine(SR.GetString(SR.PackageInstallFailedExitCode, package, exitCode)); } if (provider.GetPythonToolsService().GeneralOptions.ShowOutputWindowForPackageInstallation) { output.ShowAndActivate(); } else { output.Show(); } } return exitCode == 0; }
public static async Task Install( IPythonInterpreterFactory factory, string package, bool elevate, Redirector output = null ) { factory.ThrowIfNotRunnable("factory"); await ContinueRun(factory, output, elevate, package); }
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(SR.GetString(SR.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(SR.GetString(SR.PipInstallSucceeded)); } else { output.WriteLine(SR.GetString(SR.PipInstallFailedExitCode, exitCode)); } if (provider.GetPythonToolsService().GeneralOptions.ShowOutputWindowForPackageInstallation) { output.ShowAndActivate(); } else { output.Show(); } } } }
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); }
private static DateTime? TryGetLastWriteTimeUtc(string path, Redirector output = null) { try { return File.GetLastWriteTimeUtc(path); } catch (UnauthorizedAccessException ex) { if (output != null) { output.WriteErrorLine(string.Format("Failed to access {0}: {1}", path, ex.Message)); #if DEBUG output.WriteErrorLine(ex.ToString()); #endif } } catch (ArgumentException ex) { if (output != null) { output.WriteErrorLine(string.Format("Failed to access {0}: {1}", path, ex.Message)); #if DEBUG output.WriteErrorLine(ex.ToString()); #endif } } catch (PathTooLongException ex) { if (output != null) { output.WriteErrorLine(string.Format("Failed to access {0}: {1}", path, ex.Message)); #if DEBUG output.WriteErrorLine(ex.ToString()); #endif } } catch (NotSupportedException ex) { if (output != null) { output.WriteErrorLine(string.Format("Failed to access {0}: {1}", path, ex.Message)); #if DEBUG output.WriteErrorLine(ex.ToString()); #endif } } return null; }
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; } }
/// <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) { if (IsCriticalException(ex)) { throw; } 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) { if (IsCriticalException(ex)) { throw; } 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; }
private async Task<bool> DownloadTypings(IEnumerable<string> packages, Redirector redirector) { if (!packages.Any()) { return true; } string typingsTool = await EnsureTypingsToolInstalled(); if (string.IsNullOrEmpty(typingsTool)) { if (redirector != null) { redirector.WriteErrorLine(SR.GetString(SR.TypingsToolNotInstalledError)); } return false; } using (var process = ProcessOutput.Run( typingsTool, GetTypingsToolInstallArguments(packages), _pathToRootProjectDirectory, null, false, redirector, quoteArgs: true)) { if (!process.IsStarted) { // Process failed to start, and any exception message has // already been sent through the redirector if (redirector != null) { redirector.WriteErrorLine("could not start 'typings'"); } return false; } var i = await process; if (i == 0) { if (redirector != null) { redirector.WriteLine(SR.GetString(SR.TypingsToolInstallCompleted)); } return true; } else { process.Kill(); if (redirector != null) { redirector.WriteErrorLine(SR.GetString(SR.TypingsToolInstallErrorOccurred)); } return false; } } }
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, SR.GetString(SR.InstallPip), elevate, output); } catch (OperationCanceledException) { return false; } } else { await InstallPip(provider, factory, elevate, output); } } if (output != null) { output.WriteLine(SR.GetString(SR.PackageInstalling, 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(SR.GetString(SR.PackageInstallSucceeded, package)); } else { output.WriteLine(SR.GetString(SR.PackageInstallFailedExitCode, package, exitCode)); } if (provider.GetPythonToolsService().GeneralOptions.ShowOutputWindowForPackageInstallation) { output.ShowAndActivate(); } else { output.Show(); } } return exitCode == 0; } }
private async Task<bool> ExecuteTypingsTool(IEnumerable<string> arguments, Redirector redirector) { string typingsTool = await EnsureTypingsToolInstalled(redirector); if (string.IsNullOrEmpty(typingsTool)) { redirector?.WriteErrorLine(Resources.TypingsToolNotInstalledError); return false; } using (var process = ProcessOutput.Run( typingsTool, arguments, _pathToRootProjectDirectory, null, false, redirector, quoteArgs: true, outputEncoding: Encoding.UTF8, errorEncoding: Encoding.UTF8)) { if (!process.IsStarted) { // Process failed to start, and any exception message has // already been sent through the redirector redirector?.WriteErrorLine(Resources.TypingsToolCouldNotStart); return false; } var i = await process; if (i == 0) { redirector?.WriteLine(Resources.TypingsToolTypingsInstallCompleted); return true; } else { process.Kill(); redirector?.WriteErrorLine(Resources.TypingsToolTypingsInstallErrorOccurred); return false; } } }
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>(); } _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) { if (IsCriticalException(ex)) { throw; } if (_redirector != null) { foreach (var line in SplitLines(ex.ToString())) { _redirector.WriteErrorLine(line); } } else if (_error != null) { _error.AddRange(SplitLines(ex.ToString())); } _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. if (_redirector == null || (_redirector != null && _redirector.CloseStandardInput())) { try { _process.StandardInput.Close(); } catch (InvalidOperationException) { // StandardInput not available } } } } }
/// <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", nameof(filename)); } if (elevate) { return(RunElevated( filename, arguments, workingDirectory, redirector, quoteArgs, outputEncoding, errorEncoding)); } var psi = new ProcessStartInfo("cmd.exe") { Arguments = string.Format(@"/S /C pushd {0} & {1} {2}", QuoteSingleArgument(workingDirectory), QuoteSingleArgument(filename), GetArguments(arguments, quoteArgs)), CreateNoWindow = !visible, UseShellExecute = false }; if (!visible || (redirector != null)) { psi.RedirectStandardError = true; psi.RedirectStandardOutput = true; psi.RedirectStandardInput = true; // only set the encoding when we're redirecting the output 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)); }
/// <summary> /// Creates a virtual environment. If virtualenv is not installed, the /// task will succeed but error text will be passed to the redirector. /// </summary> public static Task Create(IServiceProvider provider, IPythonInterpreterFactory factory, string path, Redirector output = null) { factory.ThrowIfNotRunnable(); return ContinueCreate(provider, factory, path, false, output); }
/// <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) { 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); foreach (var line in lines) { redirector.WriteLine(line); } } catch (Exception) { redirector.WriteErrorLine("Failed to obtain standard output from elevated process."); } try { var lines = File.ReadAllLines(errFile); foreach (var line in lines) { redirector.WriteErrorLine(line); } } catch (Exception) { redirector.WriteErrorLine("Failed to obtain standard error from elevated process."); } } finally { try { File.Delete(outFile); } catch { } try { File.Delete(errFile); } catch { } } }; } return(result); }
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(SR.GetString(SR.PackageInstalling, 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(SR.GetString(SR.PackageInstallSucceeded, package)); } else { output.WriteLine(SR.GetString(SR.PackageInstallFailedExitCode, package, exitCode)); } if (provider.GetPythonToolsService().GeneralOptions.ShowOutputWindowForPackageInstallation) { output.ShowAndActivate(); } else { output.Show(); } } return exitCode == 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; }