كيف يمكنني تشغيل تطبيق آخر داخل لوحة من برنامج C # الخاص بي؟

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

سؤال

لقد كنت أقرأ الكثير حول كيفية تشغيل تطبيق من داخل برنامج C # (Process.Start ())، لكنني تمكن من العثور على أي معلومات حول كيفية تشغيل هذا التطبيق الجديد في لوحة من برنامج C # الخاص بي وبعد على سبيل المثال، أود أن انقر فوق الزر انقر لفتح Notepad.exe ضمن طلبي، وليس خارجيا.

هل كانت مفيدة؟

المحلول

لا أعرف ما إذا كان هذا لا يزال هو الشيء الموصى به، ولكن يسمح لك إطار "ربط الكائنات والضمان" بتضمين بعض الأشياء / الضوابط مباشرة في طلبك. من المحتمل أن يعمل هذا فقط في بعض التطبيقات، لست متأكدا مما إذا كان المفكرة هو واحد منهم. لأشياء بسيطة حقا مثل المفكرة، من المحتمل أن يكون لديك وقت أسهل في العمل مع عناصر تحكم مربع النص التي توفرها أي متوسطة تستخدمها (مثل WinForms).

إليك رابط معلومات OLE للبدء:

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

نصائح أخرى

باستخدام API Win32 من الممكن "تناول" تطبيق آخر. في الأساس، يمكنك الحصول على أعلى النافذة لهذا التطبيق وتعيين الوالد لتكون مقبض اللوحة الذي تريد وضعه فيه. إذا كنت لا تريد تأثير نمط 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's window
            SetParent(p.MainWindowHandle, panel1.Handle);
        }

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

لقد رأيت مثالا آخر حيث أطلق عليهم waitforinputidle بدلا من النوم. لذلك سيكون الرمز مثل هذا:

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

مشروع الرمز لديه مقالة جيدة واحدة العملية برمتها: استضافة تطبيقات EXE في مشروع WinForm

  • إضافة بعض الحل في الإجابة .. **

ساعدني هذا الرمز في قفص بعضها القابل للتنفيذ في نموذج Windows. مثل المفكرة، Excel، Word، Acrobat Reader N الكثيرين المزيد ...

لكنه لن يعمل لبعض التطبيقات. كما في بعض الأحيان عندما تبدأ عملية بعض التطبيقات .... انتظر وقت الخمول ... ومحاولة الحصول على Mainwindowhandle .... حتى الوقت الذي يصبح مقبض النافذة الرئيسية فارغا .....

لذلك لقد فعلت خدعة واحدة لحل هذا

إذا حصلت على مقبض النافذة الرئيسية ك NULL ... ثم ابحث في جميع عمليات الرن على Sytem وابحث عنك ... ثم احصل على HADLE الرئيسية من العملية واللوحة المحددة كوالديها.

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

هناك حل آخر مثير للاهتمام لتطبيق 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 إزالة التأخير المزعج.

enter image description here

إذا كنت ترغب في تشغيل المفكرة داخل تطبيقك، فمن المحتمل أن تكون أفضل من مكون محرر النصوص. من الواضح أن هناك مربع نص أساسي يأتي مع WinForms، لكنني أظن أن المزيد من المكونات المتقدمة التي تقدم وظيفة المفكرة (أو أفضل) يمكن العثور عليها على InterWeb.

أعرف أن هذا ممكن إذا كان التطبيق الآخر يمكن إرفاق نفسه بمقبض نافذة Win32. على سبيل المثال، لدينا تطبيق منفصل C # الذي يستضيف تطبيق DirectX داخل أحد نوافذه. أنا لست على دراية بالتفاصيل الدقيقة لكيفية تنفيذ ذلك، لكنني أعتقد فقط اجتياز Win32 Handle من اللوحة الخاصة بك إلى التطبيق الآخر يكفي لهذا التطبيق لإرفاق سطح DirectX الخاص به.

لاحظت أن جميع الإجابات السابقة تستخدم وظائف مكتبة مستخدمي WIN32 الأقدم لإنجاز هذا. أعتقد أن هذا سيعمل في عظم الحالات، ولكن ستعمل أقل موثوقية مع مرور الوقت.

الآن، عدم القيام بذلك، لا أستطيع أن أخبرك عن مدى نجاحه، لكنني أعرف أن تقنية Windows الحالية قد تكون حلا أفضل: Desktop Windows Manager API.

DWM هي نفس التكنولوجيا التي تتيح لك رؤية معاينات الصور المصغرة الحية من التطبيقات باستخدام شريط المهام ومكلومة المهام UI. أعتقد أنه يرتبط ارتباطا وثيقا بالخدمات الطرفية البعيدة.

أعتقد أن مشكلة محتملة قد تحدث عند إجبار التطبيق على أن تكون طفلا نافذة الأصل التي ليست نافذة سطح المكتب هي أن بعض مطوري التطبيقات سيقومون بافتراضات حول سياق الجهاز (DC)، وموقف المؤشر (الماوس)، عرض الشاشة، وما إلى ذلك، والتي قد تسبب سلوكا غير منتظم أو إشكالية عندما يكون "جزءا لا يتجزأ" في النافذة الرئيسية.

أظن أنه يمكنك القضاء على هذه المشكلات إلى حد كبير من خلال الاعتماد على DWM لمساعدتك في إدارة الترجمات اللازمة للحصول على Windows يتم تقديم Windows بشكل موثوق وتفاعل مع نافذة حاوية تطبيق أخرى.

تتولى الوثائق برمجة C ++، لكنني وجدت شخصا واحدا أنتج ما يدعي هو مكتبة المجمع مفتوح المصدر C #: https://bytes.com/topic/c-sharp/answers/823547-desktop-window-manager-wrapper.. وبعد المنشور قديم، والمصدر ليس في مستودع كبير مثل Github أو Bitbucket أو Sourceforge، لذلك لا أعرف كيف هو الحالي.

اجابة قصيرة:

رقم

إجابة قليلة:

فقط إذا تم تصميم التطبيق الآخر للسماح بذلك، من خلال توفير مكونات لك لإضافة إلى التطبيق الخاص بك.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top