Paste console window into WPF window

Can I embed a console window inside a WPF window?

As a small background, at first I tried to implement a console window from scratch in WPF, which was successful, except for one huge problem - its extremely slow. See the question here:
VT100 terminal emulation in Windows WPF or Silverlight

Since this does not look like an option, I instead look at the placement of the real console window in my WPF application, which I learned about how to do this, as described here:

No console output from a WPF application?

And this is great, ideally I would like the console window to look like it is part of the rest of the WPF application. I know that this is possible using the WinForms application, as I saw it, using the SetParent Win32 API. You can see an example .NET project that does this with this CommandBar project that inserts a console window into the shell:

http://www.codeproject.com/KB/cs/commandbar.aspx

So I hope this can be done with WPF as well, but I have no idea how you will do it. Help is much appreciated (also if you have brilliant solutions to my initial problem of creating a terminal window from scratch in WPF, as this will also solve my needs).

UPDATE:

Using Reed Copsi's help, I was able to get the built-in console window. However, of course, it had to be styled and moved, otherwise it would have looked like a regular console window inside a WPF window. I need a title bar and removed large borders. While researching, I found out how to use the Win32 API to do it like this:

uint style = GetWindowLong(ConsoleManager.ConsoleWindowHandle, GWL_STYLE); style &= ~(uint)WindowStyles.WS_CAPTION; style &= ~(uint)WindowStyles.WS_THICKFRAME; style &= ~(uint)WindowStyles.WS_DLGFRAME; style &= ~(uint)WindowStyles.WS_POPUP; SetWindowLong(ConsoleManager.ConsoleWindowHandle, GWL_STYLE, style); MoveWindow(ConsoleManager.ConsoleWindowHandle, 0, 0, (int)WindowsFormsHost.ActualWidth, (int)WindowsFormsHost.ActualHeight, true); 

However, there is one big problem. For some reason, the console window has a rendering artifact. It is as if not repainted on the lower left and upper right sides. The width of the artifact is similar to the width of the title and the thick border, and in fact, if I leave, the thick border is reduced by the size of the artifact. But just repainting it will not help, as it will reappear. For example, I can move the window from the screen and go back to fix it, but soon it appears again:

artifact rendering http://img837.imageshack.us/img837/6241/renderissue.png

UPDATE 2: The effect occurs even if I do not put it in the WindowsFormsHost control. All I need to do to play is to start the console (using AllocConsole ()) and then remove the title bar using SetWindowLong. This is a win7 machine.

UPDATE 3: It seems that messing with other windows like this is not supported. The console window calculates its text field, assuming there is a signature, so there is no way around this. I think my only way to get console behavior in WPF is to write a WinForms user control and then paste it into WPF.

+7
console wpf console-application
source share
2 answers

You should be able to use the same technique as the Windows Forms application that you specified by reimagining HwndHost . You can even simply adapt the Windows Forms code and put it directly in WindowsFormsHost .

+4
source share

In addition to Reed Copsie, great advice on embedding a console window in a WPF application, an alternative strategy that is ridiculously easy to implement was to simply issue a command through the Process class and redirect the two streams to WPF's own text blocks. Here is a screenshot ...

enter image description here

This WPF application (connected to the Windows Explorer context menu for exe files) executes the program and transfers the results to the appropriate window.

It is intended to help when you want to run the console utility, and when you click on it, the utility runs in the console window and you will never know what happened. It is also connected to the "csproj" files to run MSBuild on them from Explorer.

The bottom line is that sometimes itโ€™s easier and more scalable to do it yourself, and not try to place a console window ...

The internals of this application use this class ...

 public class ProcessPiper { public string StdOut { get; private set; } public string StdErr { get; private set; } public string ExMessage { get; set; } public void Start(FileInfo exe, string args, Action<ProcessPiper>onComplete) { ProcessStartInfo psi = new ProcessStartInfo(exe.FullName, args); psi.RedirectStandardError = true; psi.RedirectStandardOutput = true; psi.UseShellExecute = false; psi.WorkingDirectory = Path.GetDirectoryName(exe.FullName); Task.Factory.StartNew(() => { try { ExMessage = string.Empty; Process process = new Process(); process.StartInfo = psi; process.Start(); process.WaitForExit(); StdOut = process.StandardOutput.ReadToEnd(); StdErr = process.StandardError.ReadToEnd(); onComplete(this); } catch (Exception ex) { ExMessage = ex.Message; } }); } } 

This class executes the named exe file and captures the output, and then calls the View Model. All coding training takes about an hour or so ...

Documents in the Process class are here: http://msdn.microsoft.com/en-us/library/system.diagnostics.process.aspx

+5
source share

All Articles