C# 以嵌入到窗体的方式打开外部exe
1 using System; 2 using System.Collections.Generic; 3 using System.Text; 4 5 using System.Diagnostics; 6 using System.Runtime.InteropServices; 7 using System.Windows.Forms; 8 9 namespace War3Screen 10 { 11 /// <summary> 12 /// 以嵌入到窗体的方式打开外部exe--kongfl888 2013 13 /// </summary> 14 class OpenExeClass 15 { 16 static Process process = null; 17 static IntPtr appWin; 18 private static string exeName = ""; 19 20 21 [DllImport("user32.dll", SetLastError = true)] 22 private static extern IntPtr FindWindow(string lpClassName, string lpWindowName); 23 24 [DllImport("user32.dll", SetLastError = true)] 25 private static extern long SetParent(IntPtr hWndChild, IntPtr hWndNewParent); 26 27 [DllImport("user32.dll", SetLastError = true)] 28 private static extern bool MoveWindow(IntPtr hwnd, int x, int y, int cx, int cy, bool 29 30 repaint); 31 32 //[DllImport("user32.dll", EntryPoint = "GetWindowThreadProcessId", SetLastError = true, 33 // CharSet = CharSet.Unicode, ExactSpelling = true, 34 // CallingConvention = CallingConvention.StdCall)] 35 //private static extern long GetWindowThreadProcessId(long hWnd, long lpdwProcessId); 36 37 //[DllImport("user32.dll", EntryPoint = "GetWindowLongA", SetLastError = true)] 38 //private static extern long GetWindowLong(IntPtr hwnd, int nIndex); 39 40 //[DllImport("user32.dll", EntryPoint = "SetWindowLongA", SetLastError = true)] 41 //private static extern long SetWindowLong(IntPtr hwnd, int nIndex, long dwNewLong); 42 43 44 //[DllImport("user32.dll", SetLastError = true)] 45 //private static extern long SetWindowPos(IntPtr hwnd, long hWndInsertAfter, long x, long 46 47 y, long cx, long cy, long wFlags); 48 49 50 //[DllImport("user32.dll", EntryPoint = "PostMessageA", SetLastError = true)] 51 //private static extern bool PostMessage(IntPtr hwnd, uint Msg, long wParam, long lParam); 52 53 //[DllImport("user32.dll", EntryPoint = "ShowWindow", SetLastError = true)] 54 //private static extern bool ShowWindow(IntPtr hWnd, uint nCmdShow); 55 56 //[DllImport("user32.dll")] 57 //[return: MarshalAs(UnmanagedType.Bool)] 58 //static extern bool GetWindowRect(IntPtr hWnd, ref RECT lpRect); 59 60 //[StructLayout(LayoutKind.Sequential)] 61 //public struct RECT 62 //{ 63 // public int Left; //最左坐标 64 // public int Top; //最上坐标 65 // public int Right; //最右坐标 66 // public int Bottom; //最下坐标 67 //} 68 69 //private const int SWP_NOOWNERZORDER = 0x200; 70 //private const int SWP_NOREDRAW = 0x8; 71 //private const int SWP_NOZORDER = 0x4; 72 //private const int SWP_SHOWWINDOW = 0x0040; 73 //private const int WS_EX_MDICHILD = 0x40; 74 //private const int SWP_FRAMECHANGED = 0x20; 75 //private const int SWP_NOACTIVATE = 0x10; 76 //private const int SWP_ASYNCWINDOWPOS = 0x4000; 77 //private const int SWP_NOMOVE = 0x2; 78 //private const int SWP_NOSIZE = 0x1; 79 //private const int GWL_STYLE = (-16); 80 //private const int WS_VISIBLE = 0x10000000; 81 //private const int WM_CLOSE = 0x10; 82 //private const int WS_CHILD = 0x40000000; 83 //private const int SW_HIDE = 0; 84 85 86 public string ExeName 87 { 88 get 89 { 90 return exeName; 91 } 92 set 93 { 94 exeName = value; 95 } 96 } 97 98 public static void OpenExe(GroupBox fm, string filefullname) 99 { 100 exeName = filefullname; 101 if (exeName == null || exeName == string.Empty) return; 102 103 try 104 { 105 // Start the process 106 process = System.Diagnostics.Process.Start(exeName); 107 108 // Wait for process to be created and enter idle condition 109 process.WaitForInputIdle(); 110 111 // Get the main handle 112 //appWin = process.MainWindowHandle; 113 114 appWin = FindWindow(null, "War3 fixer"); 115 } 116 catch (Exception ex) 117 { 118 MessageBox.Show(fm, ex.Message, "Error"); 119 } 120 121 // Put it into this form 122 SetParent(appWin, fm.Handle); 123 124 // Remove border and whatnot 125 // SetWindowLong(appWin, GWL_STYLE, WS_VISIBLE); 126 127 // Move the window to overlay it on this window 128 MoveWindow(appWin, 0, 0, fm.Width+2, fm.Height, true); 129 //RECT rc = new RECT(); 130 //GetWindowRect(appWin, ref rc); 131 //int width = rc.Right - rc.Left; //窗口的宽度 132 //int height = rc.Bottom - rc.Top; //窗口的高度 133 //int x = rc.Left; 134 //int y = rc.Top; 135 //MoveWindow(appWin, 0, 0, width, height, true); 136 137 fm.Text = "魔兽"; 138 139 } 140 141 142 public static bool CloseExe() 143 { 144 bool sc = false; 145 try 146 { 147 System.Diagnostics.Process[] processList = System.Diagnostics.Process.GetProcesses 148 149 (); 150 foreach (System.Diagnostics.Process process2 in processList) 151 { 152 if (process2.Id == process.Id) 153 { 154 process.Kill(); //结束进程 155 sc=process.WaitForExit(100000); 156 157 } 158 } 159 } 160 catch { sc = true; } 161 return sc; 162 } 163 164 public static Process IsProcessRun() 165 { 166 Process processRun = new Process(); 167 try 168 { 169 System.Diagnostics.Process[] processList = System.Diagnostics.Process.GetProcesses 170 171 (); 172 foreach (System.Diagnostics.Process process2 in processList) 173 { 174 if (process2.Id == process.Id) 175 { 176 processRun = process; 177 178 } 179 } 180 } 181 catch { } 182 183 return processRun; 184 } 185 186 187 } 188 } 189 190 191 192 主窗体退出时写FormClosed事件函数,调用CloseExe()函数 193 194 195 在控件改变大小的时候,重新MoveWindow()即可,如: 196 private void splitContainer1_Panel2_Resize(object sender, EventArgs e) 197 { 198 if (this.appWin != IntPtr.Zero) 199 { 200 MoveWindow(appWin, 0, 0, this.splitContainer1.Panel2.Width, this.splitContainer1.Panel2.Height, true); 201 } 202 base.OnResize(e); 203 }