Pregunta

He estado leyendo un montón sobre cómo activar una aplicación desde dentro de un programa en C # (Process.Start ()), pero no he t sido capaz de encontrar ninguna información sobre cómo tener esta nueva aplicación se ejecute dentro de un panel de mi programa C #. Por ejemplo, me gustaría hacer clic en un botón para abrir una aplicación Bloc de notas dentro de mi, no externamente.

¿Fue útil?

Solución

No sé si esto sigue siendo lo recomendable utilizar pero el "Object Linking and Embedding" marco le permite incluir ciertos objetos / controles directamente en su aplicación. Esto probablemente sólo funcionan para ciertas aplicaciones, no estoy seguro de si el Bloc de notas es una de ellas. Para que las cosas realmente simples, como el bloc de notas, es probable que tenga un tiempo más fácil simplemente trabajar con los controles de cuadro de texto proporcionado por el medio que está utilizando (por ejemplo, Windows Forms).

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

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

Otros consejos

El uso de la API de Win32 es posible "comer" otra aplicación. Básicamente, te dan la ventana superior de dicha aplicación y la ajuste de los padres a ser la manija del panel que desea colocarlo en. Si no desea que el efecto de estilo MDI también hay que ajustar el estilo de ventana para que sea maximizado y quitar la barra de título.

Aquí hay algunos ejemplos de código sencillo en el que 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 WaitForInputIdle en vez de dormir. Por lo que el código sería así:

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

El Proyecto de Código tiene un buen artículo uno todo el proceso: alojar aplicaciones EXE en un WinForm proyecto

  • Agregando un poco de solución en la respuesta .. **

Este código me ha ayudado a atracar algunos ejecutable en forma de ventanas. como Notepad, Excel, Word, Acrobat Reader n muchos más ...

Pero no lo puedo trabajar para algunas aplicaciones. Como a veces cuando se inicia el proceso de alguna aplicación .... esperar a que el tiempo de inactividad ... y el intento de conseguir su MainWindowHandle .... hasta el momento en el mango principal ventana se convierte en nula .....

por lo que he hecho un truco para resolver este

Si obtiene ventana mango principal como nulo ... entonces buscar todos los procesos Runnning en Inglés y encontrar a procesar ... a continuación, obtener la hadle principal del proceso y el panel de conjunto como su padre.

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

Otra solución interesante para Luch una aplicación exeternal con un recipiente 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 eliminar el retraso molesto.

introducir descripción de la imagen aquí

Si desea ejecutar el bloc de notas dentro de su aplicación que probablemente sería mejor con un componente de edición de texto. Obviamente, hay un cuadro de texto básico que viene con Windows Forms, pero sospecho componentes más avanzados que ofrecen una funcionalidad Bloc de notas (o mejor) se puede encontrar en el interweb.

Sé que esto es posible si la otra aplicación puede unirse a un identificador de ventana Win32. Por ejemplo, tenemos una aplicación de 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 acaba de pasar el Handle Win32 de su panel a la otra aplicación es suficiente para que la aplicación de adjuntar su superficie DirectX.

Me he dado cuenta de que todas las respuestas anteriores usan más antiguas funciones de la biblioteca del usuario Win32 para lograr esto. Creo que esto va a funcionar en más casos, pero funcionará con menos fiabilidad en el tiempo.

Ahora, no haber hecho esto, yo no puedo decir lo bien que va a funcionar, pero sí sé que una corriente de la tecnología de Windows podría ser una solución mejor: el escritorio de windows API de .

DWM es la misma tecnología que le permite ver vistas previas en miniatura en vivo de aplicaciones utilizando la barra de tareas y la tarea de conmutación de interfaz de usuario. Creo que está muy relacionado con los servicios de Terminales Remotas.

Creo que un problema probable que podría suceder cuando se fuerza una aplicación para ser un hijo de una ventana padre que no es la ventana de escritorio es que algunos desarrolladores de aplicaciones van a hacer suposiciones acerca del contexto de dispositivo (DC), el puntero (ratón posición), anchos de pantalla, etc., que puede causar un comportamiento errático o problemático cuando se "incrustado" en la ventana principal.

Sospecho que se puede eliminar en gran medida estos problemas apoyándose en DWM para ayudar a manejar las traducciones necesarias para tener ventanas de una aplicación fiable presentarán e interactuaron con el interior de la ventana de contenedores de otra aplicación.

La documentación asume de programación C ++, pero he encontrado una persona que ha producido lo que él dice es una biblioteca de C # envoltorio de código abierto: https://bytes.com/topic/c-sharp/answers/823547-desktop-window-manager-wrapper . El puesto es viejo, y la fuente no está en un gran repositorio GitHub como, bitbucket o sourceforge, así que no sé cómo es actual.

Respuesta corta:

No

Respuesta shortish:

Sólo si la otra aplicación está diseñada para permitir que, al proporcionar componentes para que usted agregue en su propia aplicación.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top