¿Cómo puedo ejecutar otra aplicación dentro de un panel de mi progtwig C #?

He estado leyendo mucho sobre cómo activar una aplicación desde un progtwig C # (Process.Start ()), pero no he podido encontrar ninguna información sobre cómo ejecutar esta nueva aplicación dentro de un panel de mi progtwig C # . Por ejemplo, me gustaría hacer clic en un botón para abrir un notepad.exe DENTRO de mi aplicación, no externamente.

No sé si esto sigue siendo lo recomendable, pero el marco “Enlace e incrustación de objetos” le permite incrustar ciertos objetos / controles directamente en su aplicación. Esto probablemente solo funcione para ciertas aplicaciones, no estoy seguro de si el Bloc de notas es uno de ellos. Para cosas realmente simples como el bloc de notas, probablemente le resulte más fácil simplemente trabajar con los controles del cuadro de texto proporcionados por cualquier medio que esté usando (por ejemplo, WinForms).

Aquí hay un enlace a la información OLE para comenzar:

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

Usando la API win32 es posible “comer” otra aplicación. Básicamente, obtienes la ventana superior para esa aplicación y configuras que su principal sea el controlador del panel en el que deseas ubicarla. Si no quieres el efecto de estilo MDI, también tienes que ajustar el estilo de la ventana para maximizarlo. eliminar la barra de título.

Aquí hay un código de muestra simple donde tengo un formulario con un botón y un 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); } } 

Acabo de ver otro ejemplo en el que llamaron a WaitForInputIdle en lugar de dormir. Entonces el código sería así:

 Process p = Process.Start("notepad.exe"); p.WaitForInputIdle(); SetParent(p.MainWindowHandle, panel1.Handle); 

The Code Project tiene un buen artículo uno sobre todo el proceso: Alojar aplicaciones EXE en un proyecto WinForm

  • Agregando alguna solución en Answer .. **

Este código me ha ayudado a acoplar algunos ejecutables en forma de Windows. como NotePad, Excel, Word, Acrobat Reader n muchos más …

Pero no funcionará para algunas aplicaciones. Como a veces cuando se inicia el proceso de alguna aplicación … espere el tiempo de inactividad … y trate de obtener su mainWindowHandle …. hasta que el identificador de la ventana principal se vuelva nulo …

entonces hice un truco para resolver esto

Si obtiene el identificador de la ventana principal como nulo … luego busque todos los procesos de ejecución en el sistema y encuentre su proceso … luego obtenga la configuración principal del proceso y el panel de configuración como su elemento primario.

  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 arrString = new List(); 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); } 

Otra solución interesante para cargar una aplicación exeternal con un contenedor WinForm es la siguiente:

 [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; } 

El paso a ProcessWindowStyle.Minimized de ProcessWindowStyle.Normal elimina la demora molesta.

enter image description here

Si desea ejecutar el bloc de notas dentro de su aplicación, probablemente sea mejor con un componente de editor de texto. Obviamente, hay un cuadro de texto básico con WinForms, pero sospecho que se pueden encontrar componentes más avanzados que ofrecen la funcionalidad del Bloc de notas (o superior) en el interweb.

Sé que esto es posible si la otra aplicación se puede conectar a un identificador de ventana Win32. Por ejemplo, tenemos una aplicación C # separada que aloja una aplicación DirectX dentro de una de sus ventanas. No estoy familiarizado con los detalles exactos de cómo se implementa esto, pero creo que simplemente pasando el Win32 Handle de su panel a la otra aplicación es suficiente para que esa aplicación adhiera su superficie DirectX.

Observé que todas las respuestas anteriores usan funciones anteriores de la biblioteca del usuario de Win32 para lograr esto. Creo que esto funcionará en la mayoría de los casos, pero funcionará menos confiablemente con el tiempo.

Ahora, sin haber hecho esto, no puedo decirte qué tan bien funcionará, pero sí sé que una tecnología actual de Windows podría ser una mejor solución: la API de Windows Desktop Manager .

DWM es la misma tecnología que le permite ver vistas previas en miniatura en vivo de las aplicaciones mediante la barra de tareas y la IU de cambio de tareas. Creo que está estrechamente relacionado con los servicios de Terminal Remota.

Creo que un problema probable que podría ocurrir cuando fuerce a una aplicación a ser hija de una ventana principal que no sea la ventana del escritorio es que algunos desarrolladores de aplicaciones harán suposiciones sobre el contexto del dispositivo (DC), la posición del puntero (mouse), anchos de pantalla, etc., que pueden causar un comportamiento errático o problemático cuando está “incrustado” en la ventana principal.

Sospecho que en gran medida puede eliminar estos problemas confiando en DWM para ayudarlo a administrar las traducciones necesarias para que las ventanas de una aplicación se presenten de manera confiable e interactúen dentro de la ventana del contenedor de otra aplicación.

La documentación asume la progtwigción en C ++, pero encontré que una persona que ha producido lo que afirma es una biblioteca de contenedor de código abierto C: https://bytes.com/topic/c-sharp/answers/823547-desktop-window-manager-wrapper . La publicación es antigua y la fuente no está en un gran repository como GitHub, bitbucket o sourceforge, por lo que no sé cuán actual es.

Respuesta corta:

No

Breve respuesta:

Solo si la otra aplicación está diseñada para permitirlo, proporcionando componentes para que agregue a su propia aplicación.