c#嵌入外部exe到winform软件中, EmbeddedExeTool库代码

By admin at 5 小时前 • 0人收藏 • 7人看过

遇到个特殊需求, 客户提供的dll是32位的, 那么winform编写只能是x86的, 但是我们用的摄像头库却是X64的, 

这就导致一个问题:

X86和X64不能在一个工程里同时使用

解决办法也简单:

将X64编译为一个独立的exe , 将它嵌入到x86的exe里, 因为64只是摄像头显示, 没有那么多的交互

以下代码来源于网络, 忘记出处了, 之前看到就保存了下来, 果然省了不少事

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

namespace EMT
{
    internal class EmbeddedExeTool
    {
        [DllImport("User32.dll", EntryPoint = "SetParent")]
        private static extern IntPtr SetParent(IntPtr hWndChild, IntPtr hWndNewParent);

        [DllImport("user32.dll", EntryPoint = "ShowWindow")]
        private static extern int ShowWindow(IntPtr hwnd, int nCmdShow);

        [DllImport("user32.dll", SetLastError = true)]
        private static extern bool MoveWindow(IntPtr hwnd, int x, int y, int cx, int cy, bool repaint);

        [DllImport("user32.dll")]
        private static extern int GetWindowLong(IntPtr hWnd, int nIndex);
        [DllImport("user32.dll")]
        private static extern int SetWindowLong(IntPtr hWnd, int nIndex, int dwNewLong);
        [DllImport("user32.dll", SetLastError = true)]
        private static extern IntPtr FindWindow(string lpClassName, string lpWindowName);
        IntPtr WindowHandle = IntPtr.Zero;
        private const int WS_THICKFRAME = 262144;
        private const int WS_BORDER = 8388608;
        private const int GWL_STYLE = -16;
        private const int WS_CAPTION = 0xC00000;
        private Process proApp = null;
        private Control ContainerControl = null;

        private const int WS_VISIBLE = 0x10000000;
        [DllImport("user32.dll", EntryPoint = "SetWindowLong", CharSet = CharSet.Auto)]
        private static extern IntPtr SetWindowLongPtr32(HandleRef hWnd, int nIndex, int dwNewLong);
        [DllImport("user32.dll", EntryPoint = "SetWindowLongPtr", CharSet = CharSet.Auto)]
        private static extern IntPtr SetWindowLongPtr64(HandleRef hWnd, int nIndex, int dwNewLong);

        private IntPtr SetWindowLong(HandleRef hWnd, int nIndex, int dwNewLong)
        {
            if (IntPtr.Size == 4)
            {
                return SetWindowLongPtr32(hWnd, nIndex, dwNewLong);
            }
            return SetWindowLongPtr64(hWnd, nIndex, dwNewLong);
        }
        /// <summary>
                    /// 加载外部exe程序到程序容器中
                    /// </summary>
                    /// <param name="control">要显示exe的容器控件</param>
                    /// <param name="exepath">exe的完整绝对路径</param>
        public void LoadEXE(Control control, string exepath)
        {
            ContainerControl = control;
            control.SizeChanged += Control_SizeChanged;
            ProcessStartInfo info = new ProcessStartInfo(exepath);
            info.WindowStyle = ProcessWindowStyle.Minimized;
            info.UseShellExecute = false;
            info.CreateNoWindow = false;
            proApp = Process.Start(info);
            Application.Idle += Application_Idle;
            EmbedProcess(proApp, control);
        }
        /// <summary>
                    /// 加载外部exe程序到程序容器中
                    /// </summary>
                    /// <param name="form">要显示exe的窗体</param>
                    /// <param name="exepath">exe的完整绝对路径</param>
        public void LoadEXE(Form form, string exepath)
        {
            ContainerControl = form;
            form.SizeChanged += Control_SizeChanged;
            proApp = new Process();
            proApp.StartInfo.UseShellExecute = false;
            proApp.StartInfo.CreateNoWindow = false;
            proApp.StartInfo.WindowStyle = ProcessWindowStyle.Minimized;
            proApp.StartInfo.FileName = exepath;
            proApp.StartInfo.Arguments = Process.GetCurrentProcess().Id.ToString();
            proApp.Start();
            Application.Idle += Application_Idle;
            EmbedProcess(proApp, form);
        }
        /// <summary>
                    /// 确保应用程序嵌入此容器
                    /// </summary>
                    /// <param name="sender"></param>
                    /// <param name="e"></param>
        private void Application_Idle(object sender, EventArgs e)
        {
            if (this.proApp == null || this.proApp.HasExited)
            {
                this.proApp = null;
                Application.Idle -= Application_Idle;
                return;
            }
            if (proApp.MainWindowHandle == IntPtr.Zero) return;
            Application.Idle -= Application_Idle;
            EmbedProcess(proApp, ContainerControl);
        }
        /// <summary>
                    /// 将指定的程序嵌入指定的控件
                    /// </summary>
        private void EmbedProcess(Process app, Control control)
        {
            // Get the main handle
            if (app == null || app.MainWindowHandle == IntPtr.Zero || control == null) return;
            try
            {
                // Put it into this form
                SetParent(app.MainWindowHandle, control.Handle);
                // Remove border and whatnot               
                SetWindowLong(new HandleRef(this, app.MainWindowHandle), GWL_STYLE, WS_VISIBLE);
                ShowWindow(app.MainWindowHandle, (int)ProcessWindowStyle.Maximized);
                MoveWindow(app.MainWindowHandle, 0, 0, control.Width, control.Height, true);
            }
            catch (Exception ex3)
            {
                Console.WriteLine(ex3.Message);
            }
        }
        /// <summary>
                    /// 嵌入容器大小改变事件
                    /// </summary>
        private void Control_SizeChanged(object sender, EventArgs e)
        {
            if (proApp == null)
            {
                return;
            }

            if (proApp.MainWindowHandle != IntPtr.Zero && ContainerControl != null)
            {
                MoveWindow(proApp.MainWindowHandle, 0, 0, ContainerControl.Width, ContainerControl.Height, true);
            }
        }
    }
}

使用的时候:

EmbeddedExeTool exetool = new EmbeddedExeTool();
exetool.LoadEXE(panel2, "video.exe");//debug下面的文件夹


登录后方可回帖

登 录
信息栏
本站域名

ChengXu.XYZ

投诉联系:  popdes@126.com



快速上位机开发学习,本站主要记录了学习过程中遇到的问题和解决办法及上位机代码分享

这里主要专注于学习交流和经验分享.
纯私人站,当笔记本用的,学到哪写到哪.
如果侵权,联系 Popdes@126.com

友情链接
Aardio官方
Aardio资源网


才仁机械


网站地图SiteMap

Loading...