在Winform中嵌入exe程序
|
admin
2024年1月24日 23:23
本文热度 455
|
开发环境:.NET Framework版本:4.8
开发工具:Visual Studio 2022
- 创建自定义控件,继承自
Control
,然后需要使用下面的Windows Api
#region win32 api
//设置新 窗口样式
private const int GWL_STYLE = -16;
private const int WS_VISIBLE = 0x10000000;
[DllImport("user32.dll", SetLastError = true)]
public static extern long SetParent(IntPtr hWndChild, IntPtr hWndNewParent);
[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);
public static IntPtr SetWindowLong(HandleRef hWnd, int nIndex, int dwNewLong)
{
if (IntPtr.Size == 4)
{
return SetWindowLongPtr32(hWnd, nIndex, dwNewLong);
}
return SetWindowLongPtr64(hWnd, nIndex, dwNewLong);
}
[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", SetLastError = true)]
private static extern IntPtr FindWindow(string lpClassName, string lpWindowName);
[DllImport("user32", SetLastError = true)]
private static extern int GetWindowText(IntPtr hWnd, StringBuilder lpString, int nMaxCount);
#endregion
- 以路径形式的嵌入,这个方式不太好,很多程序启动后嵌入不了
if (AppProcess != null) { Release(); } try { ProcessStartInfo startInfo = new ProcessStartInfo(appFilename); startInfo.UseShellExecute = true; startInfo.WindowStyle = ProcessWindowStyle.Minimized; AppProcess = Process.Start(startInfo); AppProcess.EnableRaisingEvents = true; AppProcess.WaitForInputIdle(); Embed(AppProcess.MainWindowHandle); } catch { Release(); } return Path.GetFileNameWithoutExtension(appFilename);
- 以窗口标题的形式嵌入,这个主要还是依赖于句柄,不过是多做了一层根据标题找句柄的封装
public string Embed(string className, string windowName) { try { IntPtr handle = FindWindow(className, windowName); Embed(handle); } catch { } return windowName; }
public string Embed(IntPtr handle) { try { SetParent(handle, this.Handle); SetWindowLong(new HandleRef(this, handle), GWL_STYLE, WS_VISIBLE); MoveWindow(handle, 0, 0, this.Width, this.Height, true); } catch { } StringBuilder title = new StringBuilder(256); GetWindowText(handle, title, title.Capacity); return title.ToString(); }
- 关于句柄和窗口标题的获取,可以使用Spy++获取,如果在Vs2022上找不到,请点击工具->获取工具和功能->单个组件->勾选C++核心功能,安装完毕后就会在工具菜单内出现
- 以下演示效果为已经预先使用Spy++获取到了标题和句柄
转载:https://mp.weixin.qq.com/s/KXyUe-ALW9nb9jKRhkXtCQ
该文章在 2024/1/24 23:23:04 编辑过