C# Winform中使用Process启动外部程序并嵌入指定容器中

最近由于多台服务器需要监测日志,每次手工开启Putty特别麻烦,掉线了又要重新来一次,所以做了个小工具。

效果图:

未命名.png

单个具体实现方法如下,有多个窗口可根据需要自己扩展,很简单就不多说了。

窗体上放一个panel

引用:

System.Runtime.InteropServices;
using System.Threading.Tasks;
using System.Diagnostics;



API接口和窗口变量声明:

[DllImport("User32.dll")]
private static extern IntPtr SetParent(IntPtr hWndChild, IntPtr hWndNewParent);
[DllImport("user32.dll")]
public static extern int ShowWindow(IntPtr hwnd, int nCmdShow);
[DllImport("user32.dll", SetLastError = true)]
public static extern bool MoveWindow(IntPtr hWnd, int X, int Y, int nWidth, int nHeight, bool bRepaint);
[DllImport("user32.dll")]
static extern bool PostMessage(IntPtr hWnd, uint Msg, int wParam, int lParam);
static uint WM_CLOSE = 0x10;
private IntPtr nastopHandle; //这个是我自己起的名字,存储的是窗口句柄
private bool closeWindow = false; //这个是窗口关闭的标志


Load事件中启动线程:

private void Form1_Load(object sender, EventArgs e)
 {
     nastopHandle = IntPtr.Zero;           
     FormBorderStyle = FormBorderStyle.None;
     WindowState = FormWindowState.Maximized;
     Task tsk = new Task(NASHTop);
     tsk.Start();            
 }

启动putty,掉线自动重连:

putty我用的是putty60,配置可以自动运行命令,程序只要启动并指定profile就可以了,putty必须配置为掉线自动退出。

private void NASHTop()
 {
     Process pr = new Process();
     ProcessStartInfo ps = new ProcessStartInfo();
     ps.FileName = @"C:\putty60.exe"; //putty位置
     ps.Arguments = " -load NASHTop"; //参数
     ps.WindowStyle = ProcessWindowStyle.Minimized;
     pr.StartInfo = ps;
     while (!closeWindow)
     {
         //nastopHandle == IntPtr.Zero判断是否第一次运行,pr.HasExited判断是否已退出。
         if (nastopHandle == IntPtr.Zero || pr.HasExited)
         {
             //这一段主要是等putty主窗口显示出来,如果显示的是配置窗口则会一直等,所以必须保证上面的参数是正确的
             pr.Start();
             pr.Refresh();
             while (pr.MainWindowTitle.Trim() == "" || pr.MainWindowTitle.Trim() == "PuTTY Configuration")
             {
                 if (pr.HasExited)
                     pr.Start();
                 System.Threading.Thread.Sleep(1000);
                 pr.Refresh();                        
             }
             nastopHandle = pr.MainWindowHandle; //把句柄放到变量里
             Invoke(new MethodInvoker(() => SetParent(nastopHandle, panel1.Handle)));//放到panel1里
             ShowWindow(pr.MainWindowHandle, 3);//显示窗口
             Invoke(new MethodInvoker(() => MoveWindow(nastopHandle, 0, 0, panel1.Width, panel1.Height - 10, true)));//实现DOCK功能
         }
         System.Threading.Thread.Sleep(1000);//等待1秒后返回检查是否关闭
     }
     PostMessage(nastopHandle, WM_CLOSE, 0, 0);//当while中断后,发送关闭消息给启动的putty
 }

panel大小变化事件,将putty填充整个panel,实现dock功能:

private void panel2_SizeChanged(object sender, EventArgs e)
{
  MoveWindow(nastopHandle, 0, 0, panel2.Width, panel2.Height - 10, true); //这里-10是留有一些空间,主要是因为主窗口设置成了没有边框,关闭时不好选择
}





标签:
版权所有原创文章,转载请保留或注明出处:http://261k.com/post/20170830ersdfgre.html