Подтвердить что ты не робот

Как запустить другое приложение в панели моей программы на С#?

Я читал много о том, как запускать приложение изнутри программы С# (Process.Start()), но я не смог найти какую-либо информацию о том, как запустить это новое приложение в панели моя программа на С#. Например, я бы хотел, чтобы кнопка щелкнула, чтобы открыть файл notepad.exe в моем приложении, а не снаружи.

4b9b3361

Ответ 1

Я не знаю, рекомендуется ли это использовать, но структура "Связывание объектов и встраивание" позволяет встраивать определенные объекты/элементы управления непосредственно в ваше приложение. Это, вероятно, будет работать только для определенных приложений, я не уверен, является ли "Блокнот" одним из них. Для действительно простых вещей, таких как блокнот, вам, вероятно, будет легче работать с элементами управления текстовыми полями, предоставляемыми любым используемым носителем (например, WinForms).

Здесь ссылка на информацию OLE для начала работы:

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

Ответ 2

Используя win32 API, можно "съесть" другое приложение. В основном вы получаете верхнее окно для этого приложения и устанавливаете его родителем как дескриптор панели, в которую вы хотите поместить его. Если вы не хотите эффекта стиля MDI, вам также нужно настроить стиль окна, чтобы сделать его максимально возможным и удалите строку заголовка.

Вот несколько простых примеров кода, где у меня есть форма с кнопкой и панелью:

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 window
            SetParent(p.MainWindowHandle, panel1.Handle);
        }

        [DllImport("user32.dll")]
        static extern IntPtr SetParent(IntPtr hWndChild, IntPtr hWndNewParent);
    }
}

Я только что увидел еще один пример, где они вместо WaitForInputIdle называли WaitForInputIdle. Таким образом, код будет выглядеть следующим образом:

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

В Code Project есть хорошая статья: весь процесс: Хостинг EXE-приложений в проекте WinForm

Ответ 3

  • Добавление некоторого решения в ответ.. **

Этот код помог мне прикрепить некоторый исполняемый файл в виде окна. как NotePad, Excel, word, Acrobat reader и многое другое...

Но он не будет работать для некоторых приложений. Как иногда, когда вы запускаете процесс какого-либо приложения... ждите простоя... и попытайтесь получить его mainWindowHandle.... до тех пор, пока главный дескриптор окна не станет нулевым.

поэтому я сделал один трюк, чтобы решить эту проблему.

Если вы получите дескриптор главного окна как null... затем выполните поиск всех процессов runnning в sytem и найдите процесс... затем получите главный адлей процесса и панель set в качестве родителя.

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

Ответ 4

Если вы хотите запустить блокнот внутри своего приложения, вероятно, вам будет лучше с компонентом текстового редактора. Очевидно, что основное текстовое поле, которое поставляется с WinForms, но я подозреваю, что более продвинутые компоненты, предлагающие функциональность "Блокнот" (или лучше), можно найти на веб-сайте.

Ответ 5

Я знаю, что это возможно, если другое приложение может подключиться к дескриптору окна win32. Например, у нас есть отдельное приложение С#, на котором размещается приложение DirectX внутри одного из его окон. Я не знаком с точными сведениями о том, как это реализовано, но я думаю, что просто передать win32 Handle вашей панели в другое приложение достаточно, чтобы приложение применило его поверхность DirectX.

Ответ 6

Я замечаю, что все предыдущие ответы используют более старые функции библиотеки пользователей Win32 для выполнения этого. Я думаю, что это будет работать в большинстве случаев, но со временем будет работать менее надежно.

Теперь, не сделав этого, я не могу сказать вам, насколько он будет работать, но я знаю, что нынешняя технология Windows может быть лучшим решением: Desktop Desktop Manager.

DWM - это та же технология, которая позволяет просматривать живые миниатюрные превью приложений, используя интерфейс панели задач и переключателя задач. Я считаю, что он тесно связан с удаленными службами терминалов.

Я думаю, что вероятная проблема, которая может произойти, когда вы вынуждаете приложение быть дочерним элементом родительского окна, которое не является окном рабочего стола, заключается в том, что некоторые разработчики приложений сделают предположения о контексте устройства (DC), указателе (мышь), ширины экрана и т.д., что может вызвать неустойчивое или проблемное поведение, когда оно "встроено" в главное окно.

Я подозреваю, что вы можете в значительной степени устранить эти проблемы, полагаясь на DWM, чтобы помочь вам управлять переводами, необходимыми для надежного представления окон приложений и взаимодействия с ними внутри другого окна контейнера приложения.

Документация предполагает программирование на С++, но я обнаружил, что один человек, который создал то, что он утверждает, представляет собой библиотеку с открытым исходным кодом С#: https://bytes.com/topic/c-sharp/answers/823547-desktop-window-manager-wrapper, Сообщение старое, и источник не находится в большом репозитории, таком как GitHub, bitbucket или sourceforge, поэтому я не знаю, насколько это актуально.

Ответ 7

Другим интересным решением для exeternal приложения с контейнером WinForm является следующее:

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

Шаг в ProcessWindowStyle.Minimized из ProcessWindowStyle.Normal удаляет раздражающую задержку.

введите описание изображения здесь

Ответ 8

Короткий ответ:

Нет

Краткий ответ:

Только если другое приложение предназначено для его разрешения, предоставив компоненты для добавления в ваше собственное приложение.