Come posso eseguire un'altra applicazione all'interno di un pannello del mio programma C #?

StackOverflow https://stackoverflow.com/questions/758494

Domanda

Ho letto un sacco su come attivare un'applicazione dall'interno di un programma C # (Process.Start ()), ma mi rifugio t stato in grado di trovare tutte le informazioni su come avere questa nuova applicazione eseguita all'interno di un pannello di il mio programma C #. Ad esempio, mi piacerebbe uno scatto del tasto per aprire una notepad.exe all'interno della mia applicazione, non esternamente.

È stato utile?

Soluzione

Non so se questa è ancora la cosa consiglia di utilizzare, ma il "Object Linking and Embedding" framework consente di incorporare alcuni oggetti / comandi direttamente nella vostra applicazione. Questo sarà probabilmente funziona solo per alcune applicazioni, non sono sicuro se il Blocco note è uno di loro. Per le cose davvero semplici come blocco note, probabilmente avrete un tempo più facile solo lavorando con i controlli casella di testo qualunque supporto che si sta utilizzando (per esempio WinForms).

Ecco un link alle informazioni OLE per iniziare:

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

Altri suggerimenti

Utilizzando l'API Win32 è possibile "mangiare" un'altra applicazione. In sostanza si ottiene la finestra superiore per l'applicazione e impostare è genitore di essere il manico del pannello che si desidera metterlo in. Se non si desidera che l'effetto stile MDI si hanno anche per modificare lo stile della finestra per renderla massimizzato e rimuovere la barra del titolo.

Ecco alcuni esempi di codice semplice dove ho un form con un pulsante e un pannello:

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

Ho appena visto un altro esempio in cui hanno chiamato WaitForInputIdle invece di dormire. Quindi il codice sarebbe simile a questo:

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

Il progetto di codice ha un buon articolo uno l'intero processo: hosting di applicazioni EXE in una WinForm progetto

  • L'aggiunta di qualche soluzione in risposta .. **

Questo codice mi ha aiutato ad attraccare qualche eseguibile in forma finestre. come Notepad, Excel, Word, Acrobat reader n molti di più ...

Ma non funzionerà per alcune applicazioni. Come a volte quando si avvia processo di alcune applicazioni .... attendere per il tempo di inattività ... e il cercare di ottenere la sua mainWindowHandle .... fino al momento della maniglia della finestra principale diventa nulla .....

così ho fatto un trucco per risolvere questo

Se si ottiene handle della finestra principale, come nulla ... quindi cercare tutti i processi runnning sul sytem e trovare si elabora ... poi ottenere il hadle principale del processo e il pannello insieme come 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);
     }

Un'altra soluzione interessante Luch un'applicazione exeternal con un contenitore WinForm è il seguente:

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

Il passo per ProcessWindowStyle.Minimized dal ProcessWindowStyle.Normal rimuovere il fastidioso ritardo.

entrare descrizione dell'immagine qui

Se si desidera eseguire notepad all'interno della vostra applicazione che si sarebbe probabilmente meglio di con una componente editor di testo. C'è, ovviamente, una casella di testo di base che viene fornito con WinForms, ma ho il sospetto componenti più avanzate, che offrono funzionalità di Blocco note (o superiore) può essere trovato sul interweb.

So che questo è possibile se l'altra applicazione in grado di legarsi a un handle di finestra Win32. Ad esempio, abbiamo un'applicazione # C separata che ospita un'applicazione DirectX all'interno di una delle sue finestre. Non ho dimestichezza con i dettagli esatti di come questo è implementato, ma credo che solo di passaggio la Handle Win32 del pannello per l'altra applicazione è sufficiente per l'applicazione di allegare la sua superficie DirectX.

Ho notato che tutte le risposte precedenti utilizzano vecchie Win32 funzioni di libreria utente per raggiungere questo obiettivo. Penso che questo funzionerà in più i casi, ma funziona meno affidabile nel tempo.

Ora, non avendo fatto questo, non posso dirvi quanto bene funzionerà, ma so che una tecnologia attuale di Windows potrebbe essere una soluzione migliore: Desktop manager di Windows API .

DWM è la stessa tecnologia che permette di vedere in tempo reale le anteprime in miniatura di applicazioni che utilizzano la barra delle applicazioni e task switcher UI. Credo che è strettamente legato ai servizi di terminale remoto.

Credo che un problema probabile che potrebbe accadere quando si forza un app per essere un bambino di una finestra genitore che non è la finestra del desktop è che alcuni sviluppatori di applicazioni potranno fare ipotesi sul contesto di periferica (DC), puntatore (mouse posizione), larghezze schermo, ecc, che può provocare il comportamento irregolare o problematico quando è "embedded" nella finestra principale.

Ho il sospetto che si può in gran parte eliminare questi problemi basandosi sui DWM per aiutarvi a gestire le traduzioni necessarie per avere le finestre di un'applicazione affidabile essere presentati e interagito con al suo interno finestra contenitore di un'altra applicazione.

La documentazione presuppone di programmazione C ++, ma ho trovato una persona che ha prodotto quello che egli sostiene è un open source libreria C # involucro: https://bytes.com/topic/c-sharp/answers/823547-desktop-window-manager-wrapper . Il post è vecchio, e la fonte non è su un grande repository come GitHub, bitbucket o sourceforge, quindi non so come corrente sia.

Risposta breve:

No

Risposta piuttosto corto:

Solo se l'altra applicazione è stata progettata per permettere che, fornendo componenti per aggiungere nella vostra applicazione.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top