namespace Client.Pages
{
class NetTermHost : HwndHost
{
public IntPtr hwndHost;
private IntPtr hookId = new IntPtr(3);
private HookProc hookProc;
private Process appProc;
protected override HandleRef BuildWindowCore(HandleRef hwndParent)
{
appProc = new Process();
appProc.StartInfo.WindowStyle = ProcessWindowStyle.Hidden;
appProc.StartInfo.FileName = @"D:\greeninst\netterm\netterm.exe";
//设置要连接的主机名,这样启动以后就立即连接了
appProc.StartInfo.Arguments = "192.168.88.128";
appProc.Start();
//等待初始化完成,实现有点土
Thread.Sleep(1000);
hwndHost = Win32Native.FindWindow("NetTermClass", null);
//设置为WS_CHILD风格
uint oldStyle = Win32Native.GetWindowLong(hwndHost, Win32Native.GWL_STYLE);
//&~WS_BORDER去掉边框,这样看起来更像一个内嵌的程序,注意()的作用,改变默认的优先级
Win32Native.SetWindowLong(hwndHost, Win32Native.GWL_STYLE, (oldStyle | Win32Native.WS_CHILD)&~Win32Native.WS_BORDER);
//将netterm的父窗口设置为HwndHost,爹地我来了
Win32Native.SetParent(hwndHost, hwndParent.Handle);
//窗口最大化
Win32Native.ShowWindow(hwndHost.ToInt32(), Win32Native.SW_MAXIMIZE);
//隐藏netterm在任务栏上的按钮
HideTaskBarButton();
//隐藏netterm的工具栏
HideNetTermToolBar();
//由于登录过程非常长,所以不要在这里等太久,否则界面像死了一样,所以启动线程来操作
ThreadStart ts = new ThreadStart(
delegate()
{
//自动登录telnet
AutoLogin();
}
);
Thread thread = new Thread(ts);
thread.Start();
hookProc = new HookProc(MyHookHandler);
//设置钩子,截获主窗口界面消息循环
//对当前的窗口,使用IntPtr.Zero
HookApi.SetWindowsHookEx(hookId.ToInt32(), hookProc, IntPtr.Zero,
HookApi.GetCurrentThreadId());
return new HandleRef(this, hwndHost);
}
private int MyHookHandler(int code, IntPtr wparam, ref MSG msg)
{
//如果是当前Host的消息,则将其转发给netterm程序
if (msg.hwnd == this.Handle)
{
HandleRef handleRef = new HandleRef(this, hwndHost);
Win32Native.SendMessage(handleRef, (uint)msg.message, msg.wParam, msg.lParam);
}
int nextHook = HookApi.CallNextHookEx(hookId, code, wparam, ref msg);
return nextHook;
}
private void HideTaskBarButton()
{
IntPtr vHandle = Win32Native.FindWindow("Shell_TrayWnd", null);
vHandle = Win32Native.FindWindowEx(vHandle, IntPtr.Zero, "ReBarWindow32", IntPtr.Zero);
vHandle = Win32Native.FindWindowEx(vHandle, IntPtr.Zero, "MSTaskSwWClass", IntPtr.Zero);
vHandle = Win32Native.FindWindowEx(vHandle, IntPtr.Zero, "ToolbarWindow32", IntPtr.Zero);
//得到任务栏中按钮的数目
int vCount = Win32Native.SendMessage(new HandleRef(this, vHandle), (uint)Win32Native.TB_BUTTONCOUNT, IntPtr.Zero, IntPtr.Zero).ToInt32();
//认为最后一个按钮就是被嵌套程序的按钮,删除它
Win32Native.SendMessage(new HandleRef(this, vHandle), Win32Native.TB_DELETEBUTTON, new IntPtr(vCount - 1), IntPtr.Zero);
}
private void HideNetTermToolBar()
{
IntPtr toolBarWin = Win32Native.FindWindowEx(hwndHost, IntPtr.Zero, "ToolbarWindow32", IntPtr.Zero);
Win32Native.ShowWindow(toolBarWin.ToInt32(), 0);
}
private void AutoLogin()
{
Thread.Sleep(10000);
//输用户名
SendString("yzk\n");
Thread.Sleep(1000);
//输密码
SendString("123456\n");
Thread.Sleep(1000);
//进入目录
SendString("cd /mnt/hgfs/NAHA/src/\n");
Thread.Sleep(1000);
//运行字符终端
SendString("python FrontEnd.py\n");
}
//模拟按键
private void SendString(String s)
{
foreach(char c in s)
{
Win32Native.SendMessage(new HandleRef(this, hwndHost), Win32Native.WM_CHAR, new IntPtr(c), IntPtr.Zero);
}
}
protected override void DestroyWindowCore(HandleRef hwnd)
{
HandleRef handleRef = new HandleRef(this, hwndHost);
//关闭netterm窗口
//Win32Native.SendMessage(handleRef, Win32Native.WM_CLOSE, IntPtr.Zero, IntPtr.Zero);
//很黄很暴力,直接杀死
appProc.Kill();
//有bug,如果netterm已经连上远程主机,那么如果不退出就close的话会弹出对话框,这就会造成主程序无法退出
//几种策略:杀死netterm、发送模拟键点击“是”按钮、把netterm释放出来让用户决定、只是demo而已不管它
//没有主菜单的bug
//由于是拦截消息循环搞的,所以有可能有潜在的bug
Win32Native.DestroyWindow(hwnd.Handle);
HookApi.UnhookWindowsHookEx(hookId);
}
}
}