This is a console emulator control that embeds a fully functional console view in a Windows Forms window. It is capable of running any console application with full interactivity and advanced console functions. Applications will detect it as an actual console and will not fall back to the output redirection mode with reduced interactivity or formatting.

The control can be used to run a console process in the console emulator. The console process is the single command executed in the control, which could be a simple executable (the console emulator is not usable after it exits), or an interactive shell like cmd or powershell or bash, which in turn can execute multiple commands, either by user input or programmatically with ConEmuSession.WriteInputText. The console emulator is what implements the console and renders the console view in the control. A new console emulator (represented by a RunningSession) is Start">started for each console process. After the root console process terminates, the console emulator might remain open (see Start spawns a new console emulator for a console process in it. You cannot run more than one console emulator (or console process) simultaneousely.

Inheritance: System.Windows.Forms.Control
Exemple #1
0
        private static Form CreatePingForm()
        {
            var form = new Form() {AutoSize = true, AutoSizeMode = AutoSizeMode.GrowAndShrink, Padding = new Padding(10), Text = "Ping Command"};

            FlowLayoutPanel stack;
            form.Controls.Add(stack = new FlowLayoutPanel() {Dock = DockStyle.Fill, AutoSize = true, AutoSizeMode = AutoSizeMode.GrowAndShrink, FlowDirection = FlowDirection.TopDown});

            stack.Controls.Add(new Label() {AutoSize = true, Dock = DockStyle.Top, Text = "Running the ping command.", Padding = new Padding(5)});
            Label labelWaitOrResult;
            stack.Controls.Add(labelWaitOrResult = new Label() {AutoSize = true, Dock = DockStyle.Top, Text = "Please wait…", BackColor = Color.Yellow, Padding = new Padding(5)});

            ConEmuControl conemu;
            var sbText = new StringBuilder();
            stack.Controls.Add(conemu = new ConEmuControl() {AutoStartInfo = null, MinimumSize = new Size(800, 600), Dock = DockStyle.Top});
            ConEmuSession session = conemu.Start(new ConEmuStartInfo() {AnsiStreamChunkReceivedEventSink = (sender, args) => sbText.Append(args.GetMbcsText()), ConsoleProcessCommandLine = "ping 8.8.8.8"});
            session.ConsoleProcessExited += delegate
            {
                Match match = Regex.Match(sbText.ToString(), @"\(.*\b(?<pc>\d+)%.*?\)", RegexOptions.Multiline);
                if(!match.Success)
                {
                    labelWaitOrResult.Text = "Ping execution completed, failed to parse the result.";
                    labelWaitOrResult.BackColor = Color.PaleVioletRed;
                }
                else
                {
                    labelWaitOrResult.Text = $"Ping execution completed, lost {match.Groups["pc"].Value} per cent of packets.";
                    labelWaitOrResult.BackColor = Color.Lime;
                }
            };
            session.ConsoleEmulatorClosed += delegate { form.Close(); };

            return form;
        }
 public ConEmuExecutionHost(Core core, ConEmuControl control, string conEmuExe)
 {
     this.core = core;
     this.control = control;
     this.conEmuExe = conEmuExe;
     backupHost = new DefaultExecutionHost();
     config = LoadConfigFromResource();
     StartPowerShellExecutionHost();
     this.core.ConfigReloaded += CoreConfigReloadedHandler;
 }
        public override void Reset()
        {
            if (_terminal != null)
            {
                KillProcess();
                Controls.Remove(_terminal);
                _terminal.Dispose();
            }

            Controls.Add(_terminal = new ConEmuControl() { Dock = DockStyle.Fill, AutoStartInfo = null /* don't spawn terminal until we have gotten the command */});
        }
        public override void Reset()
        {
            ConEmuControl oldTerminal = _terminal;

            _terminal = new ConEmuControl()
            {
                Dock = DockStyle.Fill,
                AutoStartInfo = null, /* don't spawn terminal until we have gotten the command */
                IsStatusbarVisible = false
            };

            if (oldTerminal != null)
            {
                KillProcess(oldTerminal);
                _panel.Controls.Remove(oldTerminal);
                oldTerminal.Dispose();
            }

            _panel.Controls.Add(_terminal);
        }
        /// <summary>
        /// Adds a tab with console interface to Git over the current working copy. Recreates the terminal on tab activation if user exits the shell.
        /// </summary>
        private void FillTerminalTab()
        {
            if (!EnvUtils.RunningOnWindows() || !Module.EffectiveSettings.Detailed.ShowConEmuTab.ValueOrDefault)
                return; // ConEmu only works on WinNT
            TabPage tabpage;
            string sImageKey = "Resources.IconConsole";
            CommitInfoTabControl.ImageList.Images.Add(sImageKey, Resources.IconConsole);
            CommitInfoTabControl.Controls.Add(tabpage = new TabPage(_consoleTabCaption.Text));
            tabpage.ImageKey = sImageKey; // After adding page

            // Delay-create the terminal window when the tab is first selected
            CommitInfoTabControl.Selecting += (sender, args) =>
            {
                if (args.TabPage != tabpage)
                    return;
                if (terminal == null) // Lazy-create on first opening the tab
                {
                    tabpage.Controls.Clear();
                    tabpage.Controls.Add(
                        terminal = new ConEmuControl()
                        {
                            Dock = DockStyle.Fill,
                            AutoStartInfo = null,
                            IsStatusbarVisible = false
                        }
                    );
                }
                if (terminal.IsConsoleEmulatorOpen) // If user has typed "exit" in there, restart the shell; otherwise just return
                    return;

                // Create the terminal
                var startinfo = new ConEmuStartInfo();
                startinfo.StartupDirectory = Module.WorkingDir;
                startinfo.WhenConsoleProcessExits = WhenConsoleProcessExits.CloseConsoleEmulator;

                // Choose the console: bash from git with fallback to cmd
                string sJustBash = "bash.exe"; // Generic bash, should generally be in the git dir, less configured than the specific git-bash
                string sJustSh = "sh.exe"; // Fallback to SH

                string cmdPath = new[] { sJustBash, sJustSh }.
                    Select(shell =>
                      {
                          string shellPath;
                          if (PathUtil.TryFindShellPath(shell, out shellPath))
                              return shellPath;
                          return null;
                      }).
                      Where(shellPath => shellPath != null).
                      FirstOrDefault();

                if (cmdPath == null)
                {
                    startinfo.ConsoleProcessCommandLine = ConEmuConstants.DefaultConsoleCommandLine;
                }
                else
                {
                    startinfo.ConsoleProcessCommandLine = cmdPath + " --login -i";
                }
                startinfo.ConsoleProcessExtraArgs = " -new_console:P:\"<Solarized Light>\"";

                // Set path to git in this window (actually, effective with CMD only)
                if (!string.IsNullOrEmpty(AppSettings.GitCommandValue))
                {
                    string dirGit = Path.GetDirectoryName(AppSettings.GitCommandValue);
                    if (!string.IsNullOrEmpty(dirGit))
                        startinfo.SetEnv("PATH", dirGit + ";" + "%PATH%");
                }

                terminal.Start(startinfo);
            };
        }
Exemple #6
0
	    /// <summary>
	    /// Adds a tab with console interface to Git over the current working copy. Recreates the terminal on tab activation if user exits the shell.
	    /// </summary>
	    private void FillTerminalTab()
	    {
		    if(!EnvUtils.RunningOnWindows() || !Module.EffectiveSettings.Detailed.ShowConEmuTab.ValueOrDefault)
			    return; // ConEmu only works on WinNT
		    TabPage tabpage;
		    string sImageKey = "Resources.IconConsole";
		    CommitInfoTabControl.ImageList.Images.Add(sImageKey, Resources.IconConsole);
		    CommitInfoTabControl.Controls.Add(tabpage = new TabPage("Console"));
		    tabpage.ImageKey = sImageKey; // After adding page

		    // Delay-create the terminal window when the tab is first selected
		    CommitInfoTabControl.Selecting += (sender, args) =>
		    {
			    if(args.TabPage != tabpage)
				    return;
			    if(terminal == null) // Lazy-create on first opening the tab
			    {
				    tabpage.Controls.Clear();
				    tabpage.Controls.Add(terminal = new ConEmuControl() {Dock = DockStyle.Fill, AutoStartInfo = null});
			    }
			    if(terminal.IsConsoleEmulatorOpen) // If user has typed "exit" in there, restart the shell; otherwise just return
				    return;

			    // Create the terminal
			    var startinfo = new ConEmuStartInfo();
			    startinfo.StartupDirectory = Module.WorkingDir;
			    startinfo.WhenConsoleProcessExits = WhenConsoleProcessExits.CloseConsoleEmulator;

			    // Choose the console: bash from git with fallback to cmd
			    string sGitBashFromUsrBin = "";/*This is not a console program and is not reliable yet, suppress for now.*/ //Path.Combine(Path.Combine(Path.Combine(AppSettings.GitBinDir, ".."), ".."), "git-bash.exe"); // Git bin dir is /usr/bin under git installdir, so go 2x up
			    string sGitBashFromBinOrCmd = "";/*This is not a console program and is not reliable yet, suppress for now.*/ //Path.Combine(Path.Combine(AppSettings.GitBinDir, ".."), "git-bash.exe"); // In case we're running off just /bin or /cmd
		        var gitDir = Path.GetDirectoryName(AppSettings.GitCommandValue);
			    string sJustBash = Path.Combine(gitDir, "bash.exe"); // Generic bash, should generally be in the git dir, less configured than the specific git-bash
			    string sJustSh = Path.Combine(gitDir, "sh.exe"); // Fallback to SH
			    startinfo.ConsoleProcessCommandLine = new[] {sGitBashFromUsrBin, sGitBashFromBinOrCmd, sJustBash, sJustSh}.Where(File.Exists).FirstOrDefault() ?? ConEmuConstants.DefaultConsoleCommandLine; // Choose whatever exists, or default CMD shell
                if(startinfo.ConsoleProcessCommandLine != ConEmuConstants.DefaultConsoleCommandLine)
                {
                    startinfo.ConsoleProcessCommandLine += " --login -i";
                }

			    // Set path to git in this window (actually, effective with CMD only)
			    if(!string.IsNullOrEmpty(AppSettings.GitCommand))
			    {
				    string dirGit = Path.GetDirectoryName(AppSettings.GitCommand);
				    if(!string.IsNullOrEmpty(dirGit))
					    startinfo.SetEnv("PATH", dirGit + ";" + "%PATH%");
			    }

			    terminal.Start(startinfo);
		    };
	    }
Exemple #7
0
		private static Form RenderView(Form form)
		{
			form.Size = new Size(800, 600);

			ConEmuControl conemu;
			form.Controls.Add(conemu = new ConEmuControl() {Dock = DockStyle.Fill, MinimumSize = new Size(200, 200), IsStatusbarVisible = true});
			if(conemu.AutoStartInfo != null)
			{
				conemu.AutoStartInfo.SetEnv("one", "two");
				conemu.AutoStartInfo.SetEnv("geet", "huub");
				conemu.AutoStartInfo.GreetingText = "• Running \"cmd.exe\" as the default shell in the terminal. \n\n";
				//conemu.AutoStartInfo.GreetingText = "\"C:\\Program Files\\Git\\bin\\git.exe\" fetch --progress \"--all\" ";	// A test specimen with advanced quoting
				conemu.AutoStartInfo.IsEchoingConsoleCommandLine = true;
			}
			//conemu.AutoStartInfo = null;
			TextBox txt;
			form.Controls.Add(txt = new TextBox() {Text = "AnotherFocusableControl", AutoSize = true, Dock = DockStyle.Top});

			FlowLayoutPanel stack;
			form.Controls.Add(stack = new FlowLayoutPanel() {FlowDirection = FlowDirection.LeftToRight, Dock = DockStyle.Top, AutoSize = true, AutoSizeMode = AutoSizeMode.GrowAndShrink});

			Button btn;
			stack.Controls.Add(btn = new Button() {Text = "Paste Command", AutoSize = true, Dock = DockStyle.Left});
			btn.Click += delegate { conemu.RunningSession?.WriteInputText("whois microsoft.com" + Environment.NewLine); };

			stack.Controls.Add(btn = new Button() {Text = "Write StdOut", AutoSize = true, Dock = DockStyle.Left});
			btn.Click += delegate { conemu.RunningSession?.WriteOutputText("\x001B7\x001B[90mEcho \"Hello world!\"\x001B[m\x001B8"); };

			stack.Controls.Add(btn = new Button() {Text = "Query HWND", AutoSize = true, Dock = DockStyle.Left});
			btn.Click += delegate { conemu.RunningSession?.BeginGuiMacro("GetInfo").WithParam("HWND").ExecuteAsync().ContinueWith(task => txt.Text = $"ConEmu HWND: {Regex.Replace(task.Result.Response, "\\s+", " ")}", TaskScheduler.FromCurrentSynchronizationContext()); };

			stack.Controls.Add(btn = new Button() {Text = "Query PID", AutoSize = true, Dock = DockStyle.Left});
			btn.Click += delegate { conemu.RunningSession?.BeginGuiMacro("GetInfo").WithParam("PID").ExecuteAsync().ContinueWith(task => txt.Text = $"ConEmu PID: {Regex.Replace(task.Result.Response, "\\s+", " ")}", TaskScheduler.FromCurrentSynchronizationContext()); };

			stack.Controls.Add(btn = new Button() {Text = "Kill Payload", AutoSize = true, Dock = DockStyle.Left});
			btn.Click += delegate { conemu.RunningSession?.KillConsoleProcessAsync(); };

			stack.Controls.Add(btn = new Button() {Text = "Ctrl+C", AutoSize = true, Dock = DockStyle.Left});
			btn.Click += delegate { conemu.RunningSession?.SendControlCAsync(); };

			CheckBox checkStatusBar;
			stack.Controls.Add(checkStatusBar = new CheckBox() {Text = "StatusBar", Checked = conemu.IsStatusbarVisible});
			checkStatusBar.CheckedChanged += delegate { conemu.IsStatusbarVisible = checkStatusBar.Checked; };

			TextBox txtOutput = null;

			stack.Controls.Add(btn = new Button() {Text = "&Ping", AutoSize = true, Dock = DockStyle.Left});
			btn.Click += delegate
			{
				if(conemu.IsConsoleEmulatorOpen)
				{
					MessageBox.Show(form, "The console is busy right now.", "Ping", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
					return;
				}
				if(txtOutput == null)
					form.Controls.Add(txtOutput = new TextBox() {Multiline = true, Dock = DockStyle.Right, Width = 200});
				conemu.Start(new ConEmuStartInfo() {ConsoleProcessCommandLine = "ping ya.ru", IsEchoingConsoleCommandLine = true, AnsiStreamChunkReceivedEventSink = (sender, args) => txtOutput.Text += args.GetMbcsText(), WhenConsoleProcessExits = WhenConsoleProcessExits.KeepConsoleEmulatorAndShowMessage, ConsoleProcessExitedEventSink = (sender, args) => txtOutput.Text += $"Exited with ERRORLEVEL {args.ExitCode}.", GreetingText = $"This will showcase getting the command output live in the backend.{Environment.NewLine}As the PING command runs, the textbox would duplicate its stdout in real time.{Environment.NewLine}{Environment.NewLine}"});
			};

			stack.Controls.Add(btn = new Button() {Text = "&Choice", AutoSize = true, Dock = DockStyle.Left});
			btn.Click += delegate
			{
				conemu.RunningSession?.CloseConsoleEmulator();
				DialogResult result = MessageBox.Show(form, "Keep terminal when payload exits?", "Choice", MessageBoxButtons.YesNoCancel, MessageBoxIcon.Question);
				if(result == DialogResult.Cancel)
					return;
				ConEmuSession session = conemu.Start(new ConEmuStartInfo() {ConsoleProcessCommandLine = "choice", IsEchoingConsoleCommandLine = true, WhenConsoleProcessExits = result == DialogResult.Yes ? WhenConsoleProcessExits.KeepConsoleEmulatorAndShowMessage : WhenConsoleProcessExits.CloseConsoleEmulator, ConsoleProcessExitedEventSink = (sender, args) => MessageBox.Show($"Your choice is {args.ExitCode} (powered by startinfo event sink).")});
#pragma warning disable 4014
				ShowMessageForChoiceAsync(session);
#pragma warning restore 4014
			};

			return form;
		}
 public ConsoleEmulatorOutputControl()
 {
     Controls.Add(_terminal = new ConEmuControl() {Dock = DockStyle.Fill, AutoStartInfo = null /* don't spawn terminal until we have gotten the command */});
 }
Exemple #9
0
 private void InitializeConsole()
 {
     var c = new ConEmuControl();
     c.Dock = DockStyle.Bottom;
     c.Height = 200;
     c.AutoStartInfo = null;
     c.Visible = true;
     Controls.Add(c);
     conControl = c;
     conHost = new ConEmuExecutionHost(core, conControl, core.Config.Apps[AppKeys.ConEmu].Exe);
     core.ProcessExecutionHost = conHost;
 }
 private static void KillProcess(ConEmuControl terminal)
 {
     ConEmuSession session = terminal.RunningSession;
     if (session != null)
         session.SendControlCAsync();
 }