public bool Execute(string command, object[] inputs) { if (ConsoleStatus.IsBusy) { NuGetUIThreadHelper.JoinableTaskFactory.Run(() => VSOutputConsole.WriteLineAsync(Resources.PackageManagerConsoleBusy)); throw new NotSupportedException(Resources.PackageManagerConsoleBusy); } if (!string.IsNullOrEmpty(command)) { WpfConsole.SetExecutionMode(true); // Cast the ToolWindowPane to PowerConsoleToolWindow // Access the IHost from PowerConsoleToolWindow as follows PowerConsoleToolWindow.WpfConsole.Host // Cast IHost to IAsyncHost // Also, register for IAsyncHost.ExecutedEnd and return only when the command is completed var powerShellConsole = (IPrivateWpfConsole)WpfConsole; var host = powerShellConsole.Host; var asynchost = host as IAsyncHost; if (asynchost != null) { asynchost.ExecuteEnd += PowerConsoleCommand_ExecuteEnd; } // Here, we store the snapshot of the powershell Console output text buffer // Snapshot has reference to the buffer and the current length of the buffer // And, upon execution of the command, (check the commandexecuted handler) // the changes to the buffer is identified and copied over to the VS output window if (powerShellConsole.InputLineStart != null && powerShellConsole.InputLineStart.Value.Snapshot != null) { _snapshot = powerShellConsole.InputLineStart.Value.Snapshot; } // We should write the command to the console just to imitate typical user action before executing it // Asserts get fired otherwise. Also, the log is displayed in a disorderly fashion NuGetUIThreadHelper.JoinableTaskFactory.Run(() => powerShellConsole.WriteLineAsync(command)); return(host.Execute(powerShellConsole, command, null)); } return(false); }
private void ConsoleCommandExecuteEnd(object sender, EventArgs e) { // Flush the change in console text buffer onto the output window for testability // If the VSOutputConsole could not be obtained, just ignore if (VSOutputConsole != null && _snapshot != null) { if (_previousPosition < _snapshot.Length) { VSOutputConsole.WriteLine(_snapshot.GetText(_previousPosition, (_snapshot.Length - _previousPosition))); } _previousPosition = _snapshot.Length; } ((IAsyncHost)sender).ExecuteEnd -= ConsoleCommandExecuteEnd; WpfConsole.SetExecutionMode(false); // This does NOT imply that the command succeeded. It just indicates that the console is ready for input now VSOutputConsole.WriteLine(Resources.PackageManagerConsoleCommandExecuted); ExecuteEnd.Raise(this, EventArgs.Empty); }