views:

4220

answers:

7

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.

Thanks.

+2  A: 
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.

Samuel
I like your short answer best. :-)
McWafflestix
+1  A: 

You can't - the program you're starting is a seperate process, not a thread within your own process.

sgreeve
+3  A: 

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:

http://en.wikipedia.org/wiki/Object_Linking_and_Embedding

Andy White
A: 

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.

Steve Haigh
+1  A: 

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.

Anthony Brien
+1  A: 

Thanks for all the feedback. Notepad was probably a bad example because what I'd be looking to do is open third party software in the C# panel triggered by user button clicks. I wanted the users to be able to run these programs without leaving my application environment. Anyone have any ideas? I was thinking a windows desktop dock perhaps?

Alex
Like everyone has said, you can't do it unless the application is built to permit it. Almost none of them are.
John Saunders
+9  A: 

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

Luke Quinane
That's a seriously cool little trick. Thanks for sharing!
Simon Gillbee