首页 > 编程语言 >C#的winform如何嵌套另一个exe程序

C#的winform如何嵌套另一个exe程序

时间:2023-08-18 10:49:36浏览次数:44  
标签:IntPtr exe C# System private int using winform

这篇文章主要介绍了C#的winform如何嵌套另一个exe程序问题,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教   −

目录

C#winform嵌套另一个exe程序

一共有二种方法,也不知道作者从哪里复制来的,先感谢原作者。

首先建立一个程序,加2个按钮,为了区分,界面修改成红色。

第一种

1.建立一个主程序,加一个panel1,为了区分背景是绿色

2.代码调用

3.所有代码

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Diagnostics; using System.Drawing; using System.Linq; using System.Runtime.InteropServices; using System.Text; using System.Threading.Tasks; using System.Windows.Forms; namespace WindowsFormsApp1 {     public partial class Form1 : Form     {         public Form1()         {             InitializeComponent();         }         /// <summary>         /// 嵌入外部exe         /// </summary>         public 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);                 }             }         }         private void Form1_Load(object sender, EventArgs e)         {             EmbeddedExeTool exetool = new EmbeddedExeTool();             //WindowsFormsApp4.exe 为要嵌入外部exe的具体路径             exetool.LoadEXE(panel1, AppDomain.CurrentDomain.BaseDirectory+ "WindowsFormsApp4.exe");//debug下面的文件夹         }     } }

4.效果很好。

红配绿,绝配。 

第二种

和第一种方式有点不一样。 

1.建立一个winform主程序,为了区分背景是绿色

2.把代码直接复制进去,修改命名空间,再加上一个load事件即可

3.代码

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 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; namespace WindowsFormsApp1 {     public partial class Form1 : Form     {         private const int GWL_STYLE = (-16);         private const int WS_VISIBLE = 0x10000000;         EventHandler appIdleEvent = null;         Action<object, EventArgs> appIdleAction = null;         Process m_AppProcess;         [DllImport("user32.dll", EntryPoint = "SetWindowLong", CharSet = CharSet.Auto)]         public static extern IntPtr SetWindowLongPtr32(HandleRef hWnd, int nIndex, int dwNewLong);         [DllImport("user32.dll", EntryPoint = "SetWindowLongPtr", CharSet = CharSet.Auto)]         public static extern IntPtr SetWindowLongPtr64(HandleRef hWnd, int nIndex, int dwNewLong);         [DllImport("user32.dll", SetLastError = true)]         private static extern long SetParent(IntPtr hWndChild, IntPtr hWndNewParent);         //SetParent(IntPtr hWndChild, IntPtr hWndNewParent);这个方法很重要,就是将hWndChild指向开启exe的窗体嵌入到hWndNewParent窗体的某个控件上,或者是窗体本 身的容器         [DllImport("user32.dll", SetLastError = true)]         private static extern bool MoveWindow(IntPtr hwnd, int x, int y, int cx, int cy, bool repaint);         // MoveWindow(IntPtr hwnd, int x, int y, int cx, int cy, bool repaint);这个方法是windows的api,见名知意,是移动hwnd所指的窗体到指定的位置,并且指定是否需要重绘         public static IntPtr SetWindowLong(HandleRef hWnd, int nIndex, int dwNewLong)         {             if (IntPtr.Size == 4)             {                 return SetWindowLongPtr32(hWnd, nIndex, dwNewLong);             }             return SetWindowLongPtr64(hWnd, nIndex, dwNewLong);         }         public Form1()         {             InitializeComponent();             appIdleAction = new Action<object, EventArgs>(Application_Idle);             appIdleEvent = new EventHandler(appIdleAction);         }         /// <summary>         /// 确保应用程序嵌入此容器,再次确认exe嵌入,如果不调用这个方法,程序不一定能嵌入外部exe         /// </summary>         /// <param name="sender"></param>         /// <param name="e"></param>         void Application_Idle(object sender, EventArgs e)         {             if (this.m_AppProcess == null || this.m_AppProcess.HasExited)             {                 this.m_AppProcess = null;                 Application.Idle -= appIdleEvent;//这一步一直不知道有什么用,但是不用这行代码程序有时候能嵌入有时候又不行                 return;             }             if (m_AppProcess.MainWindowHandle == IntPtr.Zero) return;             Application.Idle -= appIdleEvent;             EmbedProcess(m_AppProcess, this);         }         /// <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);             }             catch (Exception ex1)             {                 Console.WriteLine(ex1.Message);             }             try             {                 // Remove border and whatnot                               SetWindowLong(new HandleRef(this, app.MainWindowHandle), GWL_STYLE, WS_VISIBLE);             }             catch (Exception ex2)             {                 Console.WriteLine(ex2.Message);             }             try             {                 MoveWindow(app.MainWindowHandle, 0, 0, control.Width, control.Height, true);             }             catch (Exception ex3)             {                 Console.WriteLine(ex3.Message);             }         }         private void Form1_Load(object sender, EventArgs e)         {             //以下这段代码是通过命令行方式调起一个exe程序,获取这个程序的句柄然后嵌入主的winform窗体中             ProcessStartInfo info = new ProcessStartInfo(AppDomain.CurrentDomain.BaseDirectory + "WindowsFormsApp4.exe");//debug下面的文件夹             info.WindowStyle = ProcessWindowStyle.Minimized;             info.UseShellExecute = false;             info.CreateNoWindow = false;             m_AppProcess = System.Diagnostics.Process.Start(info);             Application.Idle += appIdleEvent;             try             {                 EmbedProcess(m_AppProcess, this);             }             catch (Exception ex)             {                 Console.WriteLine(ex.Message);             }         }     } }

4.效果

可见,第一种和第二种的效果有所区别的。

拓展。

WPF签入winform

1.依然用上面的winform程序,把输出类型改成类库

  

2.建立一个WPF程序,引用System.Windows.Forms和WindowsFormsIntegration,红色。绿色是步骤1生产的dll

3.在wpf中增加WindowsFormsHost控件

4.cs后台代码

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Windows; using System.Windows.Controls; using System.Windows.Data; using System.Windows.Documents; using System.Windows.Input; using System.Windows.Media; using System.Windows.Media.Imaging; using System.Windows.Navigation; using System.Windows.Shapes; using WindowsFormsApp4; namespace WpfApp1 {     /// <summary>     /// MainWindow.xaml 的交互逻辑     /// </summary>     public partial class MainWindow : Window     {         public MainWindow()         {             InitializeComponent();             Form1 mainform = new Form1();             mainform.TopLevel = false;             winform.Child = mainform;         }     } }

5.效果

总结

以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。

标签:IntPtr,exe,C#,System,private,int,using,winform
From: https://www.cnblogs.com/chinasoft/p/17639751.html

相关文章

  • AndroidStudio SurfaceView SurfaceHolder关系
    电视机就像是屏幕,而SurfaceView则是你要在屏幕上显示的内容。然而,你不能直接在电视机上直接绘制内容,就像你不能直接在SurfaceView上绘制内容一样。这就是SurfaceHolder登场的地方。SurfaceHolder就像是遥控器,它是控制你如何在电视屏幕上显示内容的工具。你通过遥控器来切......
  • idea导入新springboot项目时 如何进行configure相关的配置 启动项目
    idea导入springboot项目运行教程前置要求①具备Java环境,并且可以通过Maven进行安装项目依赖;②具备IntelliJIDEA工具,推荐专业版,社区版也不影响;③具备Mysql5.7或以上版本数据库;④具备Navicat数据库可视化管理工具;⑤推荐使用GoogleChrome、Firefox浏览器idea导入项目的运行教......
  • IfcDayInMonthNumber
    IfcDayInMonthNumber类型定义IfcDayInMonthNumber是一个整数,用于定义指定日期在一个月中的位置。 类型:整数 IFC1.5.1中的新型。IFC4添加规则ValidRange的位置 FormalPropositionsRuleDescriptionValidRangeThevalidrangeforpositioningadayinamonth......
  • 笔记整理--C语言--数组指针和指针数组的区别 - hongcha_717 - 博客园——转载
    【转载】:原文http://www.cnblogs.com/hongcha717/archive/2010/10/24/1859780.html数组指针和指针数组的区别数组指针(也称行指针)定义int(*p)[n];()优先级高,首先说明p是一个指针,指向一个整型的一维数组,这个一维数组的长度是n,也可以说是p的步长。也就是说执行p+1时,p要跨过n个......
  • c# - 如何在圆角 WPF 窗体中创建圆角矩形?
    我正在WPF中创建一个应用程序,我想要圆角。收到。现在窗体是无边框的,我正在尝试创建一个圆角矩形并将其放在顶部,使其看起来像Windows应用程序的顶部栏。我做不到。这是我的代码:<BorderCornerRadius="50,0,50,0"BorderBrush="Black"BorderThickness="2"Background="......
  • C# SECS/GEM协议
    一、概念  SECS/GEMI标准(制造设备通信和控制的通用模型)指的是一组用于管理制造设备和工厂主机系统之间通信的半导体行业标准,由国际半导体协议SEMI发起并维护。GEM基于其他较低级别的标准,如下:图片后补协议名称用途SECS-I定义RS-232通信的标准(报文)HSMS定义TCP/......
  • 安森美 IDE(基于Eclipse)报头文件缺少的解决方法
    安森美IDE(基于Eclipse)报头文件缺少,但是能正常跳转到头文件在这里面将路径包含进来,建议两个都添加一次  在项目上点击右键,然后点击Index下的Rebuild重建 ......
  • SpringCloud 微服务的协调者
    一、什么是SpringCloud1、功能:配置管理、服务注册、服务发现、断路器、智能路由、负载均衡、服务间调用、微代理、一次性令牌、思维导图模板、全局锁、领导选举、分布式消息、分布式会话、集群状态2、SpringCloud与SpringBoot的关系SpringBoot是构建SpringCloud架......
  • MySQL客户端工具 phpMyAdmin MySQL Workbench HeidiSQL Sequel Pro DBeaver
    MySQL是一种流行的关系型数据库管理系统,它被广泛用于Web应用程序和企业级应用程序的开发中。目前,市面上有不少好用的MySQL客户端工具,如Navicat,SQLyog等。但这些产品虽然功能强大,却都是收费的,而且费用还不低。幸运的是,收费产品并不是你的唯一选择,目前也有不少开源的工具。如果你不想......
  • 轻量级容器运行时:Containerd的部署与使用
    containerd作为轻量级容器运行时,被认为是最热门的Docker替代方案,目前已在阿里云、腾讯云等多家云商得到了支持,相信未来会有非常不错的发展前景。在前面的文章已对产品的功能架构进行了介绍,本文我们将更进一步,来学习containerd的部署与使用。01—部署containerd1.下载二进制文件 $......