0

SOLVED (Scroll down for the solution)

I know this question was many asked but no solution worked for me.
My goal is to get a cmd window bound to my Win Forms Application.

What I have tried so far:

My Form Load:

Process cmd = new Process();
cmd.StartInfo.UseShellExecute = false;
cmd.StartInfo.FileName = "cmd.exe";
cmd.StartInfo.Arguments = "/K ";
cmd.StartInfo.CreateNoWindow = false;
cmd.StartInfo.RedirectStandardInput = true;

//cmd.StartInfo.RedirectStandardOutput = true;
//cmd.StartInfo.RedirectStandardError = true;

//cmd.OutputDataReceived += new DataReceivedEventHandler(this.ProcessOutputHandler);
//cmd.ErrorDataReceived += new DataReceivedEventHandler(this.ProcessErrorHandler);

cmd.Start();

writer = cmd.StandardInput;

SetParent(cmd.MainWindowHandle, panel1.Handle);

My Hook Command:

[DllImport("user32.dll")]
static extern IntPtr SetParent(IntPtr hWndChild, IntPtr hWndNewParent);

The Process shows up and turns invisible like it would be eaten, but is not shown in my Panel.

As you can see in my comments, I've tried to get the output redirected in some events which i could build my own "input / output" window, but the events don't get called.
My cmd.exe stays black and prints it's output in the window form of itself instead of calling my events.

EDIT: Forgot two lines of code to "start reading" the output and error streams..

EDIT: Done, i've got everything i need. After migrating my Process into my panel his handle wasn't able to be received anymore so i had to get it before the migration.

The second thing was, that my window get's minimized after beeing migrated (or at least is outside the visible boundaries of the panel)

Here is the code for all those who want to migrate a program visible in theirs:

using System.Runtime.InteropServices;
using System.Threading;
using System.Diagnostics;


private void button1_Click(object sender, EventArgs e)
    {
        /*
        cmd.StartInfo.UseShellExecute = false;
        cmd.StartInfo.FileName = "cmd.exe";
        cmd.StartInfo.Arguments = "/K ";
        cmd.StartInfo.CreateNoWindow = false;
        cmd.StartInfo.WindowStyle = ProcessWindowStyle.Normal;
        */
        cmd = Process.Start("cmd.exe");
        

        Thread.Sleep(500);

        IntPtr hWnd = cmd.MainWindowHandle; //FindWindow("Notepad", "Unbenannt - Editor");

        SetParent(cmd.MainWindowHandle, panel1.Handle);

        Thread.Sleep(500);
        
        if (!hWnd.Equals(IntPtr.Zero))
        {
            ShowWindowAsync(hWnd, SW_SHOWMAXIMIZED);
        }

    }

    private const int SW_SHOWNORMAL = 1;
    private const int SW_SHOWMINIMIZED = 2;
    private const int SW_SHOWMAXIMIZED = 3;
    private const int SW_SHOWNOACTIVATE = 4;
    private const int SW_RESTORE = 9;
    private const int SW_SHOWDEFAULT = 10;

    [DllImport("user32.dll")]
    private static extern bool ShowWindowAsync(IntPtr hWnd, int nCmdShow);

    [DllImport("user32.dll", SetLastError = true)]
    static extern IntPtr FindWindow(string lpClassName, string lpWindowName);

    [DllImport("user32.dll")]
    static extern IntPtr SetParent(IntPtr hWndChild, IntPtr hWndNewParent);
Yuki
  • 69
  • 10
  • I don't understand the problem. If it is because events are not fired, probably you're missing to enable it: https://learn.microsoft.com/en-us/dotnet/api/system.diagnostics.process.enableraisingevents?view=net-5.0 – PiGi78 Dec 05 '20 at 22:13
  • Are you trying to *embed* a Console Window in your app (with `CreateNoWindow = true`?) or redirect/show the output of the commands you send to stdIn in a Control? Would something like this do? [How do I get output from a command to appear in a control on a Form in real-time?](https://stackoverflow.com/a/51682585/7444103) – Jimi Dec 06 '20 at 01:04
  • Thank you for your example, i would like to get both working to use them on later projects. @Jimi – Yuki Dec 06 '20 at 09:09

0 Answers0