70 votes

Comment puis-je exécuter une autre application dans un panel de mon programme C#?

J'ai lu beaucoup sur la façon de déclencher une application à partir de l'intérieur d'un programme C# (Processus.Start()), mais je n'ai pas été en mesure de trouver toute l'information sur la façon de faire de cette nouvelle application à exécuter au sein d'un panel de mon programme C#. Par exemple, j'aimerais un clic sur un bouton pour ouvrir une notepad.exe DANS mon application, pas à l'extérieur.

Merci.

103voto

Luke Quinane Points 8257

À l'aide de l'API win32, il est possible de "manger" une autre application. Fondamentalement, vous obtenez la fenêtre du haut pour que la demande et celle du parent à la poignée du panneau que vous voulez le placer. Si vous ne voulez pas le MDI effet de style, vous devez également ajuster le style de la fenêtre pour la faire exploiter et supprimer la barre de titre.

Voici un simple exemple de code où j'ai un formulaire avec un bouton et un panneau:

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

Je viens de voir un autre exemple où ils ont appelé WaitForInputIdle au lieu de dormir. Donc, le code devrait ressembler à ceci:

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

Le Projet de Code a un bon article, l'ensemble du processus: de l'Hébergement EXE Applications dans un projet WinForm

15voto

Andy White Points 36586

Je ne sais pas si c'est encore une chose recommandée pour l'utilisation, mais la "Object Linking and Embedding" cadre vous permet d'incorporer certains objets/commandes directement dans votre application. Cela ne fonctionnera probablement pour certaines applications, je ne suis pas sûr si le bloc-notes est l'un d'entre eux. Pour des choses vraiment simples comme le bloc-notes, vous aurez probablement avoir un temps plus facile simplement de travailler avec les contrôles de zone de texte fournie par n'importe quel moyen que vous utilisez (par exemple, WinForms).

Voici un lien OLE info pour commencer:

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

6voto

Saurabh Raoot Points 11
  • L'ajout d'une solution en Réponse..**

Ce code m'a aidé à quai certains exécutable dans un formulaire windows. comme le bloc-notes, Excel, word, Acrobat reader n beaucoup plus...

Mais il l'habitude de travailler pour certaines applications. Comme parfois, quand vous commencez le processus d'une application.... attendez que le temps d'inactivité... et essayer d'obtenir son mainWindowHandle.... jusqu'au moment où la fenêtre principale de la poignée devient nulle.....

donc, j'ai fait une astuce pour résoudre ce

Si vous obtenez la fenêtre principale de la poignée de null... ensuite rechercher tous les runnning les processus sur le système et de trouver que vous traitez ... puis obtenir les principaux accepter des processus et de l'ensemble du panneau, comme son 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);
     }

1voto

Steve Haigh Points 6261

Si vous souhaitez exécuter le bloc-notes à l'intérieur de votre application, vous serait probablement mieux de le faire avec un éditeur de texte composant. Il y a évidemment un texte de base de la boîte qui vient avec WinForms, mais je soupçonne plus avancées des composants qui offrent le bloc-notes de la fonctionnalité (ou mieux) peut être trouvé sur l'interweb.

1voto

Anthony Brien Points 2069

Je sais que c'est possible si l'application peut s'attacher à un win32 poignée de la fenêtre. Par exemple, nous avons séparé application en C# qui héberge une application DirectX à l'intérieur de l'une de ses fenêtres. Je ne suis pas familier avec les détails de la façon dont cela est mis en œuvre, mais je pense que juste en passant win32 Handle de votre panneau à l'autre application est assez pour que l'application attacher sa surface DirectX.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X