Frage

Ich habe gelesen, viel auf, wie eine Anwendung auslösen aus dem Inneren eines C # -Programm (Process.Start ()), aber ich haven t konnte keine Informationen finden, wie diese neue Anwendung ausgeführt haben innerhalb einer Gruppe von mein C # -Programm. Zum Beispiel würde ich eine Schaltfläche wie Sie auf einen notepad.exe WITHIN meiner Anwendung zu öffnen, nicht von außen.

War es hilfreich?

Lösung

Ich weiß nicht, ob dies nach wie vor ist die empfohlene Sache zu verwenden, aber die „Object Linking and Embedding“ Rahmen können Sie bestimmte Objekte / Kontrollen direkt in Ihre Anwendung einbetten. Dies wird wahrscheinlich nur für bestimmte Anwendungen arbeiten, ich bin nicht sicher, ob Notepad ist einer von ihnen. Für wirklich einfache Dinge wie Notepad, werden Sie wahrscheinlich leichter haben nur mit dem Textfeld-Steuerelemente arbeiten bereitgestellt Art des Datenträger Sie verwenden (zum Beispiel WinForms).

Hier ist ein Link zu OLE Info zu beginnen:

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

Andere Tipps

die win32-API ist es möglich, „essen“ eine andere Anwendung. Grundsätzlich Sie die Top-Fenster für diese Anwendung erhalten und setzen es Eltern ist der Griff der Platte zu sein, das Sie es in platzieren möchten. Wenn Sie nicht über die MDI Arteffekt wollen auch Sie haben das Fenster Stil anzupassen, um es maximiert und entfernen Sie die Titelleiste.

Hier finden Sie einige einfache Beispielcode, wo ich ein Formular mit einer Schaltfläche haben und ein 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);
    }
}

Ich sah nur ein weiteres Beispiel, wo sie WaitForInputIdle anstatt zu schlafen genannt. So würde der Code wie folgt sein:

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

Der Code Project hat einen guten Artikel man den ganzen Prozess: Hosting EXE-Anwendungen in einem WinForm Projekt

  • Hinzufügen einiger Lösung in Antwort .. **

Dieser Code hat mir geholfen, einige ausführbare Datei in Windows Form anzudocken. wie Notizbuch, Excel, Word, Acrobat Reader n viele mehr ...

Aber es wird nicht für einige Anwendungen arbeiten. Wie manchmal, wenn Sie Prozess von einigen Anwendungen .... wartet Leerlaufzeit starten ... und den Versuch zu bekommen seine Mainwindowhandle .... bis die Zeit der Hauptfenstergriff wird null .....

so habe ich einen Trick getan, diese zu lösen

Wenn Sie Hauptfenstergriff als null bekommen ... dann alle runnning Prozesse auf Sytem suchen und finden Sie verarbeiten ... dann die Haupt hadle des Prozesses erhalten und das Set-Panel als Elternteil.

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

Eine weitere interessante Lösung, die eine exeternal Anwendung mit einem WinForm Behälter Luch ist die folgen:

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

Der Schritt ProcessWindowStyle.Minimized von ProcessWindowStyle.Normal die lästigen Verzögerung entfernen.

Wenn Sie Notizblock in Ihrem App ausführen möchten würden Sie wahrscheinlich besser aus mit einem Texteditor Komponente. Es gibt offensichtlich ein grundlegendes Textfeld, das mit WinForms kommt, aber ich vermute, erweitern Komponenten, die Editor-Funktionalität bieten (oder besser) auf dem interweb gefunden werden.

Ich weiß, das ist möglich, wenn die andere Anwendung auf einen win32 Fenstergriff befestigen. Zum Beispiel haben wir eine separate C # Anwendung, die eine DirectX-Anwendung innerhalb eines seiner Windows-Hosts. Ich bin nicht vertraut mit den genauen Einzelheiten, wie dies umgesetzt wird, aber ich denke, die win32 Handle Ihre Platte auf die anderen Anwendung gerade vorbei ist genug für diese Anwendung seiner DirectX Oberfläche zu befestigen.

Ich stelle fest, dass alle vor Antworten verwenden ältere Win32 User-Library-Funktionen, dies zu erreichen. Ich denke, diese Arbeit in wird die meisten Fälle, aber arbeiten weniger zuverlässig über die Zeit.

Nun, dies nicht getan zu haben, kann ich Ihnen nicht sagen, wie gut es funktioniert, aber ich weiß, dass eine aktuelle Windows-Technologie könnte eine bessere Lösung: die Desktop Windows Manager API .

DWM ist die gleiche Technologie, die Sie Live-Miniaturansichten von Anwendungen mit Hilfe der Taskleiste und Task Switcher UI sehen kann. Ich glaube, dass sie eng mit Remote Terminal Services verwendet ist.

Ich denke, dass ein mögliches Problem, was passieren könnte, wenn Sie eine App erzwingen, ein Kind eines Elternfensters zu sein, die nicht das Desktop-Fenster ist, dass einige Anwendungsentwickler Annahmen über den Gerätekontext machen (DC), Zeiger (Maus ) Position, Rasterweiten, etc., die unregelmäßig oder problematisches Verhalten verursachen können, wenn es im Hauptfenster „eingebettet“ ist.

Ich vermute, dass Sie diese Probleme weitgehend, indem sie sich auf DWM beseitigen können Sie die Übersetzungen verwalten zu helfen, einer Anwendung notwendig haben Fenster zuverlässig dargestellt werden und interagierten mit innerhalb einer anderen Anwendung Container Fenster.

Die Dokumentation setzt voraus, C ++ Programmierung, aber ich fand eine Person, die produziert hat, was er behauptet, ist eine Open Source C # Wrapper-Bibliothek: https://bytes.com/topic/c-sharp/answers/823547-desktop-window-manager-wrapper . Die Post ist alt, und die Quelle ist nicht auf einem großen Repository wie GitHub, bitbucket oder Sourceforge, so dass ich weiß nicht, wie Strom es ist.

Kurze Antwort:

Nein

Shortish Antwort:

Nur wenn die andere Anwendung ausgelegt ist, es zu ermöglichen, durch Komponenten bieten für Sie in Ihre eigene Anwendung hinzuzufügen.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top