I've been reading lots on how to trigger an application from inside a C# program (Process.Start()), but I haven t been able to find any information on how to have this new application run within a panel of my C# program. For example, I'd like a button click to open a notepad.exe WITHIN my application, not externally.
8 Answers
Using the win32 API it is possible to "eat" another application. Basically you get the top window for that application and set it's parent to be the handle of the panel you want to place it in. If you don't want the MDI style effect you also have to adjust the window style to make it maximised and remove the title bar.
Here is some simple sample code where I have a form with a button and a panel:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Diagnostics;
using System.Runtime.InteropServices;
using System.Threading;
namespace WindowsFormsApplication2
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
Process p = Process.Start("notepad.exe");
Thread.Sleep(500); // Allow the process to open it's window
SetParent(p.MainWindowHandle, panel1.Handle);
}
[DllImport("user32.dll")]
static extern IntPtr SetParent(IntPtr hWndChild, IntPtr hWndNewParent);
}
}
I just saw another example where they called WaitForInputIdle instead of sleeping. So the code would be like this:
Process p = Process.Start("notepad.exe");
p.WaitForInputIdle();
SetParent(p.MainWindowHandle, panel1.Handle);
The Code Project has a good article one the whole process: Hosting EXE Applications in a WinForm project

- 16,447
- 13
- 69
- 88
-
19Super helpful! the link didn't show the dll imports for their functions so i thought id share them here [DllImport("user32.dll")] static extern IntPtr SetParent(IntPtr hWndChild, IntPtr hWndNewParent); [DllImport("user32.dll")] static extern int SetWindowLong(IntPtr hWnd, int nIndex, int dwNewLong); [DllImport("user32.dll")] static extern bool MoveWindow(IntPtr Handle, int x, int y, int w, int h, bool repaint); – hrh Jan 24 '12 at 17:25
-
When I use this with IE or Chrome, top portion of the browser shows up as black. Is there a way to change this to transparent so that it shows my main window's color? – user21479 Apr 03 '15 at 01:32
-
The referenced article/code flat doesn't work for me (maybe because I'm using WPF?). Must use this: http://stackoverflow.com/questions/5836176/docking-window-inside-another-window. Also, for pinvoke imports, http://pinvoke.net is always useful. – dudeNumber4 Sep 20 '16 at 17:06
-
2Yes, experienced Windows programmers use WaitForInputIdle. Windows programmers should always look twice or more at code that uses Sleep. – Sam Hobbs Oct 13 '17 at 00:08
-
if you want to maximize the window: [DllImport("user32.dll")] private static extern bool ShowWindowAsync(IntPtr hWnd, int nCmdShow); https://social.msdn.microsoft.com/Forums/vstudio/en-US/9bde4870-1599-4958-9ab4-902fa98ba53a/how-do-i-maximizeminimize-applications-programmatically-in-c?forum=csharpgeneral – camino Nov 28 '18 at 14:18
-
This solution is working well for notepad exe, but when I'm trying to use excel exe then excel is opened outside of panel. How to restrict that? – Kiran Desai Apr 01 '19 at 12:06
-
@KiranDesai I tried the solution and [code project article](https://www.codeproject.com/Articles/9123/Hosting-EXE-Applications-in-a-WinForm-project) but both of them don't work on Win7 and Win10 2004. May I ask what's your environment to make it work? – Louis Go Aug 19 '20 at 05:28
I don't know if this is still the recommended thing to use but the "Object Linking and Embedding" framework allows you to embed certain objects/controls directly into your application. This will probably only work for certain applications, I'm not sure if Notepad is one of them. For really simple things like notepad, you'll probably have an easier time just working with the text box controls provided by whatever medium you're using (e.g. WinForms).
Here's a link to OLE info to get started:

- 86,444
- 48
- 176
- 211
Another interesting solution to luch an exeternal application with a WinForm container is the follow:
[DllImport("user32.dll")]
static extern IntPtr SetParent(IntPtr hWndChild, IntPtr hWndNewParent);
private void Form1_Load(object sender, EventArgs e)
{
ProcessStartInfo psi = new ProcessStartInfo("notepad.exe");
psi.WindowStyle = ProcessWindowStyle.Minimized;
Process p = Process.Start(psi);
Thread.Sleep(500);
SetParent(p.MainWindowHandle, panel1.Handle);
CenterToScreen();
psi.WindowStyle = ProcessWindowStyle.Normal;
}
The step to ProcessWindowStyle.Minimized
from ProcessWindowStyle.Normal remove the annoying delay.

- 13,072
- 12
- 67
- 75
-
don't sleep to wait for events that don't execute in guaranteed expected time on a realtime platform – Lodewijk Jun 08 '18 at 17:07
- Adding some solution in Answer..**
This code has helped me to dock some executable in windows form. like NotePad, Excel, word, Acrobat reader n many more...
But it wont work for some applications. As sometimes when you start process of some application.... wait for idle time... and the try to get its mainWindowHandle.... till the time the main window handle becomes null.....
so I have done one trick to solve this
If you get main window handle as null... then search all the runnning processes on sytem and find you process ... then get the main hadle of the process and the set panel as its parent.
ProcessStartInfo info = new ProcessStartInfo();
info.FileName = "xxxxxxxxxxxx.exe";
info.Arguments = "yyyyyyyyyy";
info.UseShellExecute = true;
info.CreateNoWindow = true;
info.WindowStyle = ProcessWindowStyle.Maximized;
info.RedirectStandardInput = false;
info.RedirectStandardOutput = false;
info.RedirectStandardError = false;
System.Diagnostics.Process p = System.Diagnostics.Process.Start(info);
p.WaitForInputIdle();
Thread.Sleep(3000);
Process[] p1 ;
if(p.MainWindowHandle == null)
{
List<String> arrString = new List<String>();
foreach (Process p1 in Process.GetProcesses())
{
// Console.WriteLine(p1.MainWindowHandle);
arrString.Add(Convert.ToString(p1.ProcessName));
}
p1 = Process.GetProcessesByName("xxxxxxxxxxxx");
//p.WaitForInputIdle();
Thread.Sleep(5000);
SetParent(p1[0].MainWindowHandle, this.panel2.Handle);
}
else
{
SetParent(p.MainWindowHandle, this.panel2.Handle);
}

- 1,303
- 3
- 26
- 31
I notice that all the prior answers use older Win32 User library functions to accomplish this. I think this will work in most cases, but will work less reliably over time.
Now, not having done this, I can't tell you how well it will work, but I do know that a current Windows technology might be a better solution: the Desktop Windows Manager API.
DWM is the same technology that lets you see live thumbnail previews of apps using the taskbar and task switcher UI. I believe it is closely related to Remote Terminal services.
I think that a probable problem that might happen when you force an app to be a child of a parent window that is not the desktop window is that some application developers will make assumptions about the device context (DC), pointer (mouse) position, screen widths, etc., which may cause erratic or problematic behavior when it is "embedded" in the main window.
I suspect that you can largely eliminate these problems by relying on DWM to help you manage the translations necessary to have an application's windows reliably be presented and interacted with inside another application's container window.
The documentation assumes C++ programming, but I found one person who has produced what he claims is an open source C# wrapper library: https://bytes.com/topic/c-sharp/answers/823547-desktop-window-manager-wrapper. The post is old, and the source is not on a big repository like GitHub, bitbucket, or sourceforge, so I don't know how current it is.

- 4,202
- 3
- 33
- 38
I know this is possible if the other application can attach itself to a win32 window handle. For example, we have a separate C# application that hosts a DirectX application inside one of its windows. I'm not familiar with the exact details of how this is implemented, but I think just passing the win32 Handle
of your panel to the other application is enough for that application to attach its DirectX surface.

- 6,106
- 7
- 43
- 56
If you want to run notepad inside your app you would probably be better of with a text editor component. There's obviously a basic text box that comes with WinForms, but I suspect more advanced components that offer Notepad functionality (or better) can be found on the interweb.

- 8,469
- 1
- 26
- 37
Short Answer:
No
Shortish Answer:Only if the other application is designed to allow it, by providing components for you to add into your own application.
-
5@PaulSonier - even when the short answer is completely wrong? ;-) The short answer is Yes – Chris Rogers Aug 26 '16 at 05:39
-
In the real world we often have to adapt something that was not made for that. – Vinicius Gonçalves Apr 23 '18 at 20:14