LOGO OA教程 ERP教程 模切知識(shí)交流 PMS教程 CRM教程 開(kāi)發(fā)文檔 其他文檔  
 
網(wǎng)站管理員

在C# WinForms中嵌入和控制外部程序的完整指南

admin
2025年5月25日 21:4 本文熱度 481

在開(kāi)發(fā)Windows桌面應(yīng)用程序時(shí),我們經(jīng)常需要在自己的應(yīng)用程序中嵌入并控制其他可執(zhí)行程序。本文將詳細(xì)介紹如何在C# WinForms應(yīng)用程序中實(shí)現(xiàn)這一功能,并提供多個(gè)實(shí)用示例。

基本概念

嵌入外部程序意味著將其他Windows應(yīng)用程序的窗口作為子窗口嵌入到我們的WinForms應(yīng)用程序中。這種技術(shù)通常用于:

  • 集成第三方工具
  • 創(chuàng)建復(fù)合應(yīng)用程序
  • 提供統(tǒng)一的用戶(hù)界面
  • 控制和管理多個(gè)應(yīng)用程序

技術(shù)實(shí)現(xiàn)

基本實(shí)現(xiàn)類(lèi)

創(chuàng)建一個(gè)專(zhuān)門(mén)用于管理嵌入程序的類(lèi):

using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;

namespace AppEmbedding
{
    publicclass ExternalProcessManager
    {

        // Windows API 常量  
        privateconstint GWL_STYLE = -16;
        privateconstint WS_CHILD = 0x40000000;
        privateconstint WS_VISIBLE = 0x10000000;

        // Windows API 聲明  
        privatestaticclass WindowsAPI
        {

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

            [DllImport("user32.dll")]
            public static extern int GetWindowLong(IntPtr hWnd, int nIndex);

            [DllImport("user32.dll")]
            public static extern int SetWindowLong(IntPtr hWnd, int nIndex, int dwNewLong);

            [DllImport("user32.dll")]
            public static extern bool ShowWindow(IntPtr hWnd, int nCmdShow);

            [DllImport("user32.dll")]
            public static extern bool MoveWindow(IntPtr hWnd, int X, int Y, int nWidth, int nHeight, bool bRepaint);
        }

        private Process _embeddedProcess;
        private Control _parentControl;

        public ExternalProcessManager(Control parentControl)
        
{
            _parentControl = parentControl;
        }

        public void EmbedProcess(string processPath)
        
{
            try
            {
                // 啟動(dòng)進(jìn)程 - 使用 UseShellExecute = false 可能對(duì)某些應(yīng)用程序更有效  
                ProcessStartInfo startInfo = new ProcessStartInfo(processPath)
                {
                    UseShellExecute = false,
                    CreateNoWindow = false
                };

                _embeddedProcess = Process.Start(startInfo);

                // 使用超時(shí)機(jī)制等待窗口句柄創(chuàng)建,避免無(wú)限等待  
                _embeddedProcess.WaitForInputIdle(3000);

                // 設(shè)置等待主窗口句柄的超時(shí)時(shí)間  
                DateTime timeout = DateTime.Now.AddSeconds(5);
                while (_embeddedProcess.MainWindowHandle == IntPtr.Zero)
                {
                    if (DateTime.Now > timeout)
                    {
                        thrownew TimeoutException("無(wú)法獲取進(jìn)程主窗口句柄");
                    }
                    Application.DoEvents(); // 保持UI響應(yīng)  
                    System.Threading.Thread.Sleep(100);
                }

                // 設(shè)置父窗口  
                WindowsAPI.SetParent(_embeddedProcess.MainWindowHandle, _parentControl.Handle);

                // 設(shè)置窗口樣式  
                int style = WindowsAPI.GetWindowLong(_embeddedProcess.MainWindowHandle, GWL_STYLE);
                style |= WS_CHILD | WS_VISIBLE; // 添加WS_VISIBLE確保窗口可見(jiàn)  
                WindowsAPI.SetWindowLong(_embeddedProcess.MainWindowHandle, GWL_STYLE, style);

                // 調(diào)整窗口位置和大小  
                WindowsAPI.MoveWindow(
                    _embeddedProcess.MainWindowHandle,
                    00,
                    _parentControl.ClientSize.Width,
                    _parentControl.ClientSize.Height,
                    true
                );

                // 確保父控件在尺寸變化時(shí)調(diào)整嵌入程序的大小  
                _parentControl.SizeChanged += (sender, e) =>
                {
                    if (_embeddedProcess != null && !_embeddedProcess.HasExited)
                    {
                        WindowsAPI.MoveWindow(
                            _embeddedProcess.MainWindowHandle,
                            00,
                            _parentControl.ClientSize.Width,
                            _parentControl.ClientSize.Height,
                            true
                        );
                    }
                };
            }
            catch (Exception ex)
            {
                MessageBox.Show($"嵌入進(jìn)程時(shí)出錯(cuò): {ex.Message}""錯(cuò)誤", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
        }

        public void CloseEmbeddedProcess()
        
{
            if (_embeddedProcess != null && !_embeddedProcess.HasExited)
            {
                try
                {
                    _embeddedProcess.CloseMainWindow();
                    if (!_embeddedProcess.WaitForExit(3000))
                    {
                        _embeddedProcess.Kill();
                    }
                }
                catch (Exception ex)
                {
                    MessageBox.Show($"關(guān)閉進(jìn)程時(shí)出錯(cuò): {ex.Message}""錯(cuò)誤", MessageBoxButtons.OK, MessageBoxIcon.Error);
                }
                finally
                {
                    _embeddedProcess.Dispose();
                    _embeddedProcess = null;
                }
            }
        }
    }
}

實(shí)際應(yīng)用示例

嵌入記事本示例

public partial class NotePadForm : Form
{
    private ExternalProcessManager _processManager;

    public NotePadForm()
    
{
        InitializeComponent();

        // 創(chuàng)建一個(gè)Panel用于容納記事本
        Panel notepadPanel = new Panel
        {
            Dock = DockStyle.Fill
        };
        this.Controls.Add(notepadPanel);

        _processManager = new ExternalProcessManager(notepadPanel);
    }

    private void btnEmbedNotepad_Click(object sender, EventArgs e)
    
{
        _processManager.EmbedProcess("notepad.exe");
    }

    protected override void OnFormClosing(FormClosingEventArgs e)
    
{
        _processManager.CloseEmbeddedProcess();
        base.OnFormClosing(e);
    }
}

嵌入計(jì)算器示例

public partial class CalculatorForm : Form
{
    private ExternalProcessManager _processManager;
    private Panel _calcPanel;

    public CalculatorForm()
    
{
        InitializeComponent();

        // 創(chuàng)建計(jì)算器面板
        _calcPanel = new Panel
        {
            Size = new Size(300400),
            Location = new Point(1010)
        };
        this.Controls.Add(_calcPanel);

        _processManager = new ExternalProcessManager(_calcPanel);

        Button embedButton = new Button
        {
            Text = "嵌入計(jì)算器",
            Location = new Point(32010)
        };
        embedButton.Click += EmbedCalculator_Click;
        this.Controls.Add(embedButton);
    }

    private void EmbedCalculator_Click(object sender, EventArgs e)
    
{
        _processManager.EmbedProcess("calc.exe");
    }

    protected override void OnFormClosing(FormClosingEventArgs e)
    
{
        _processManager.CloseEmbeddedProcess();
        base.OnFormClosing(e);
    }
}

常見(jiàn)問(wèn)題解決

窗口無(wú)法正確嵌入

// 確保等待窗口句柄創(chuàng)建
while (process.MainWindowHandle == IntPtr.Zero)
{
    System.Threading.Thread.Sleep(100);
    process.Refresh();
}

DPI縮放問(wèn)題

protected override void OnLoad(EventArgs e)
{
    base.OnLoad(e);
    if (Environment.OSVersion.Version.Major >= 6)
    {
        SetProcessDPIAware();
    }
}

[DllImport("user32.dll")]
private static extern bool SetProcessDPIAware();

窗口大小調(diào)整

protected override void OnResize(EventArgs e)
{
    base.OnResize(e);
    if (_embeddedProcess != null && !_embeddedProcess.HasExited)
    {
        WindowsAPI.MoveWindow(_embeddedProcess.MainWindowHandle, 
            00, _parentControl.Width, _parentControl.Height, true);
    }
}

總結(jié)

通過(guò)本文的詳細(xì)介紹和示例,你應(yīng)該能夠在C# WinForms應(yīng)用程序中成功實(shí)現(xiàn)外部程序的嵌入和控制。記住要注意進(jìn)程管理、窗口處理、性能優(yōu)化和安全性等關(guān)鍵方面。合理使用這些技術(shù)可以幫助你創(chuàng)建更強(qiáng)大和靈活的應(yīng)用程序。

?

閱讀原文:原文鏈接


該文章在 2025/5/26 10:23:05 編輯過(guò)
關(guān)鍵字查詢(xún)
相關(guān)文章
正在查詢(xún)...
點(diǎn)晴ERP是一款針對(duì)中小制造業(yè)的專(zhuān)業(yè)生產(chǎn)管理軟件系統(tǒng),系統(tǒng)成熟度和易用性得到了國(guó)內(nèi)大量中小企業(yè)的青睞。
點(diǎn)晴PMS碼頭管理系統(tǒng)主要針對(duì)港口碼頭集裝箱與散貨日常運(yùn)作、調(diào)度、堆場(chǎng)、車(chē)隊(duì)、財(cái)務(wù)費(fèi)用、相關(guān)報(bào)表等業(yè)務(wù)管理,結(jié)合碼頭的業(yè)務(wù)特點(diǎn),圍繞調(diào)度、堆場(chǎng)作業(yè)而開(kāi)發(fā)的。集技術(shù)的先進(jìn)性、管理的有效性于一體,是物流碼頭及其他港口類(lèi)企業(yè)的高效ERP管理信息系統(tǒng)。
點(diǎn)晴WMS倉(cāng)儲(chǔ)管理系統(tǒng)提供了貨物產(chǎn)品管理,銷(xiāo)售管理,采購(gòu)管理,倉(cāng)儲(chǔ)管理,倉(cāng)庫(kù)管理,保質(zhì)期管理,貨位管理,庫(kù)位管理,生產(chǎn)管理,WMS管理系統(tǒng),標(biāo)簽打印,條形碼,二維碼管理,批號(hào)管理軟件。
點(diǎn)晴免費(fèi)OA是一款軟件和通用服務(wù)都免費(fèi),不限功能、不限時(shí)間、不限用戶(hù)的免費(fèi)OA協(xié)同辦公管理系統(tǒng)。
Copyright 2010-2025 ClickSun All Rights Reserved

黄频国产免费高清视频,久久不卡精品中文字幕一区,激情五月天AV电影在线观看,欧美国产韩国日本一区二区
丝袜美腿国产综合久久 | 一区中文字幕在线日本 | 亚洲性爱之国产精品 | 亚洲国产一级在线观看 | 亚洲A在线V免费观看 | 亚洲中文色欧另类欧美 |