異世界


2012年7月6日 星期五

綁架外部程式視窗(二)

將 Win32 訊息及函式放在一個Class中。修正部分錯誤,並加入

public static int sendWindowsStringMessage(IntPtr hWnd, int wParam, string msg);

得以直接以訊息列傳送字串。

PS: 被綁架的視窗應用程式,則該程式  ThisProcess.MainWindowHandel 將被改變為 0,而無法取得 hWSnd,即無法傳送訊息。(未找到解答方法)

 

Win32 Class :

class Win32
   {
       #region WIN32定義區
       public enum ShowWindowStyles : short
       {
           SW_HIDE = 0,
           SW_SHOWNORMAL = 1,
           SW_NORMAL = 1,
           SW_SHOWMINIMIZED = 2,
           SW_SHOWMAXIMIZED = 3,
           SW_MAXIMIZE = 3,
           SW_SHOWNOACTIVATE = 4,
           SW_SHOW = 5,
           SW_MINIMIZE = 6,
           SW_SHOWMINNOACTIVE = 7,
           SW_SHOWNA = 8,
           SW_RESTORE = 9,
           SW_SHOWDEFAULT = 10,
           SW_FORCEMINIMIZE = 11,
           SW_MAX = 11
       }
 
       public const int WM_COPYDATA = 0x4A;
       public const int SWP_NOOWNERZORDER = 0x200;
       public const int SWP_NOREDRAW = 0x8;
       public const int SWP_NOZORDER = 0x4;
       public const int SWP_SHOWWINDOW = 0x0040;
       public const int WS_EX_MDICHILD = 0x40;
       public const int SWP_FRAMECHANGED = 0x20;
       public const int SWP_NOACTIVATE = 0x10;
       public const int SWP_ASYNCWINDOWPOS = 0x4000;
       public const int SWP_NOMOVE = 0x2;
       public const int SWP_NOSIZE = 0x1;
       public const int GWL_STYLE = (-16);
       public const int WS_VISIBLE = 0x10000000;
       public const int WM_CLOSE = 0x10;
       public const int WS_CHILD = 0x40000000;
 
       public const int HWND_TOP = 0x0;
       public const int WM_COMMAND = 0x0112;
       public const int WM_QT_PAINT = 0xC2DC;
       public const int WM_PAINT = 0x000F;
       public const int WM_SIZE = 0x0005;
       public const int WM_USER = 0x0400;
 
       #region User_Message(自定義訊息)
       public const int SbMsgOffset = 100;
 
       //.....................................................................
       //  WM_USER_MESSAGE_1 => 通知 OWner, __ADAM6050UDP.exe 的 HWND
       //     Lparam: HWnd
       //     WParam: nonuse
       public const int WM_USER_MESSAGE_1 = WM_USER + SbMsgOffset;
 
       //.....................................................................
       //  WM_USER_MESSAGE_2 => 通知 OWner, DI_Value
       //     Lparam: 此 ADAM6050 的IP 在 INI檔裡的Index
       //     WParam: DI_Value (16 bits)
       public const int WM_USER_MESSAGE_2 = WM_USER + SbMsgOffset + 1; //..通知 OWner DI_Value
 
 
       //.....................................................................
       //  WM_USER_MESSAGE_3 => 通知 OWner __IP_Scand.exe    的 HWND
       //     Lparam: HWnd
       //     WParam: nonuse
       public const int WM_USER_MESSAGE_3 = WM_USER + SbMsgOffset + 2;
 
 
       //.....................................................................
       //  WM_USER_MESSAGE_4 => 通知 OWner, IP_Ping 的結果
       //     Lparam: 此 IP_Scan 的IP 在 INI檔裡的Index
       //     WParam:  0:OK / 非0: ping不通
       public const int WM_USER_MESSAGE_4 = WM_USER + SbMsgOffset + 3;
 
       //.....................................................................
       //  WM_USER_MESSAGE_5 => 保留未用
       public const int WM_USER_MESSAGE_5 = WM_USER + SbMsgOffset + 4;
 
       //.....................................................................
       //  WM_USER_MESSAGE_6 => 通知 ADAM & IP_Scan 結束程式
       public const int WM_USER_MESSAGE_6 = WM_USER + SbMsgOffset + 5;
       #endregion
 
 
       [DllImport("User32.dll")]
       public static extern Int32 RegisterWindowMessage(string lpString);
 
       //For use with WM_COPYDATA and COPYDATASTRUCT
       [DllImport("User32.dll", EntryPoint = "SendMessage")]
       public static extern int SendMessage(IntPtr hWnd, int Msg, int wParam, ref COPYDATASTRUCT lParam);
 
       //For use with WM_COPYDATA and COPYDATASTRUCT
       [DllImport("User32.dll", EntryPoint = "PostMessage")]
       public static extern int PostMessage(IntPtr hWnd, int Msg, int wParam, ref COPYDATASTRUCT lParam);
 
       [DllImport("User32.dll", EntryPoint = "SendMessage")]
       public static extern int SendMessage(int hWnd, int Msg, int wParam, int lParam);
 
       [DllImport("User32.dll", EntryPoint = "PostMessage")]
       public static extern int PostMessage(int hWnd, int Msg, int wParam, int lParam);
 
       [DllImport("User32.dll", EntryPoint = "SetForegroundWindow")]
       public static extern bool SetForegroundWindow(int hWnd);
 
       [DllImport("user32.dll", EntryPoint = "GetWindowThreadProcessId", SetLastError = true,
            CharSet = CharSet.Unicode, ExactSpelling = true,
            CallingConvention = CallingConvention.StdCall)]
       public static extern long GetWindowThreadProcessId(long hWnd, long lpdwProcessId);
 
       [DllImport("user32.dll", SetLastError = true)]
       public static extern IntPtr FindWindow(string lpClassName, string lpWindowName);
 
       [DllImport("user32.dll", SetLastError = true)]
       public static extern long SetParent(IntPtr hWndChild, IntPtr hWndNewParent);
 
       [DllImport("user32.dll", EntryPoint = "GetWindowLongA", SetLastError = true)]
       public static extern long GetWindowLong(IntPtr hwnd, int nIndex);
 
       [DllImport("user32.dll", EntryPoint = "SetWindowLongA", SetLastError = true)]
       public static extern long SetWindowLong(IntPtr hwnd, int nIndex, long dwNewLong);
       //public static extern int SetWindowLong(IntPtr hWnd, int nIndex, IntPtr dwNewLong);
 
       [DllImport("user32.dll", SetLastError = true)]
       public static extern long SetWindowPos(IntPtr hwnd, long hWndInsertAfter, long x, long y, long cx, long cy, long wFlags);
 
       [DllImport("user32.dll", SetLastError = true)]
       public static extern bool MoveWindow(IntPtr hwnd, int x, int y, int cx, int cy, bool repaint);
 
       [DllImport("user32.dll", EntryPoint = "PostMessageA", SetLastError = true)]
       public static extern bool PostMessage(IntPtr hwnd, uint Msg, long wParam, long lParam);
 
       [DllImport("user32.dll")]
       public static extern void SetForegroundWindow(IntPtr hwnd);
 
       //..
       [DllImport("user32.dll")]
       public static extern bool ShowWindowAsync(IntPtr hWnd, int nCmdShow);
 
       [DllImport("user32.dll", SetLastError = true)]
       public static extern bool PostMessage(IntPtr hWnd, uint Msg, int wParam, int lParam);
 
       [DllImport("user32.dll", EntryPoint = "SetWindowPos")]
       public static extern bool SetWindowPos(IntPtr hWnd, int hWndInsertAfter, int X, int Y, int cx, int cy, uint uFlags);
 
       [DllImport("user32.dll")]
       public static extern int SendMessage(IntPtr hWnd, uint Msg, int wParam, int lParam);
 
       [DllImport("user32.dll", SetLastError = true, CharSet = CharSet.Auto)]
       public static extern uint SetWindowLong(IntPtr hwnd, int nIndex, uint newLong);
 
       [DllImport("user32.dll", CharSet = CharSet.Auto)]
       public static extern bool ShowWindow(IntPtr hWnd, short State);
 
       [DllImport("user32.dll", CharSet = CharSet.Auto, ExactSpelling = true)]
       internal static extern bool GetWindowRect(IntPtr hWnd, ref RECT rect);
 
       [DllImport("user32.dll")]
       [return: MarshalAs(UnmanagedType.Bool)]
       public static extern bool IsWindow(IntPtr hWnd);
 
       [DllImport("kernel32.dll", SetLastError = true)]
       public static extern int GetProcessId(IntPtr hWnd);
 
       public static IntPtr GethWnd(Process p)
       {
           return p.MainWindowHandle;
       }
 
 
       internal struct RECT  //Win32 數據結構
       {
           public int left;
           public int top;
           public int right;
           public int bottom;
       }
 
       //Used for WM_COPYDATA for string messages
       public struct COPYDATASTRUCT
       {
           public IntPtr dwData;
           public int cbData;
           [MarshalAs(UnmanagedType.LPStr)]
           public string lpData;
       }
 
       //.. 
       public static int sendWindowsStringMessage(IntPtr hWnd, int wParam, string msg)
       {
           int result = 0;
 
           if (IsWindow(hWnd))
           {
               byte[] sarr = System.Text.Encoding.Default.GetBytes(msg);
               int len = sarr.Length;
               COPYDATASTRUCT cds;
               cds.dwData = (IntPtr)100;
               cds.lpData = msg;
               cds.cbData = len + 1;
               result = SendMessage(hWnd, WM_COPYDATA, wParam, ref cds);
           }
 
           return result;
       }
 
       //
       //.. How to use "COPYDATASTRUCT" 
       //
       /* ==<< Message Queue >>==
       protected override void WndProc(ref Message m)
       {
           switch (m.Msg)
           {
               case WM_USER:
                   break;
               case WM_COPYDATA:
                   COPYDATASTRUCT mystr = new COPYDATASTRUCT();
                   Type mytype = mystr.GetType();
                   mystr = (COPYDATASTRUCT)m.GetLParam(mytype);
                   //this.doSomethingWithMessage(mystr.lpData);
                   break;
           }
           base.WndProc(ref m);
       }
        
        */
       #endregion
 
       #region 綁架外部程式視窗
       //..以名稱檢察 Processes 是否存在
       public static bool isProcesses(string ProName)
       {
           return (Process.GetProcessesByName(ProName).Length > 1);
       }
       public static Process RunExe(String ExeFileName, String Arg)
       {
           Process p = new Process();
           // 需要啟動的程序            
           //p.StartInfo.mResFile = @"C:\Windows\System32\notepad.exe";            
           p.StartInfo.FileName = ExeFileName;
           p.StartInfo.Arguments = Arg;
 
 
           // 最小化程序            
           p.StartInfo.WindowStyle = ProcessWindowStyle.Minimized;
 
           // 啟動           
           p.Start();
 
           return (p);
       }
       public static Process RunExeAndToChid(IntPtr ParentHandle, string ExeFileName, string args)
       {
           Process p = new Process();
           // 需要啟動的程序            
           //p.StartInfo.mResFile = @"C:\Windows\System32\notepad.exe";            
           p.StartInfo.FileName = ExeFileName;
           p.StartInfo.Arguments = args;
 
 
           // 最小化程序            
           p.StartInfo.WindowStyle = ProcessWindowStyle.Minimized;
 
           // 啟動           
           p.Start();
 
           // 必须等待,啟動程序的 Handol 未没有創建,不能控制程序             
           Thread.Sleep(5000);
 
           // 最大化啟動程序            
           ShowWindow(p.MainWindowHandle, (short)ShowWindowStyles.SW_MAXIMIZE);
 
           // 設置被绑架程序的父窗口            
           //SetParent(p.MainWindowHandle, this.Handle);
           SetParent(p.MainWindowHandle, ParentHandle);
 
           // 改變尺寸            
           ResizeControl(p, ParentHandle);
 
           return (p);
       }
 
 
       // 控制嵌入程序的位置和尺寸
       public static void ResizeControlEMS(Process p, IntPtr ParentHandle)
       {
           int TopOffset = -54;//-28;
           int LeftOffset = -8;
 
           SendMessage(p.MainWindowHandle, WM_COMMAND, WM_PAINT, 0);
           PostMessage(p.MainWindowHandle, WM_QT_PAINT, 0, 0);
 
           //.. 取得視窗大小
           RECT tempRect = new RECT();
           GetWindowRect(ParentHandle, ref tempRect);
 
           SetWindowPos(p.MainWindowHandle,
                         HWND_TOP,
                         LeftOffset,           // 0,  // 设置偏移量,把原来窗口的菜单遮住                
                         TopOffset,
                         tempRect.right - tempRect.left - LeftOffset + 10,// (int)this.Width,
                         tempRect.bottom - tempRect.top - TopOffset + 6, // (int)this.Height,
                         SWP_FRAMECHANGED);
           SendMessage(p.MainWindowHandle, WM_COMMAND, WM_SIZE, 0);
       }
       public static void ResizeControl(Process p, IntPtr ParentHandle)
       {
           SendMessage(p.MainWindowHandle, WM_COMMAND, WM_PAINT, 0);
           PostMessage(p.MainWindowHandle, WM_QT_PAINT, 0, 0);
 
           //.. 取得視窗大小
           RECT tempRect = new RECT();
           GetWindowRect(ParentHandle, ref tempRect);
 
           SetWindowPos(p.MainWindowHandle,
                         HWND_TOP,
                         0,  // 设置偏移量,把原来窗口的菜单遮住                
                         0,
                         tempRect.right - tempRect.left,// (int)this.Width,
                         tempRect.bottom - tempRect.top, // (int)this.Height,
                         SWP_FRAMECHANGED);
           SendMessage(p.MainWindowHandle, WM_COMMAND, WM_SIZE, 0);
       }
       public static void ResizeControlHwnd(IntPtr pHWND, IntPtr ParentHandle)
       {
           //.. 取得視窗大小
           RECT tempRect = new RECT();
           GetWindowRect(ParentHandle, ref tempRect);
 
           SetWindowPos(pHWND,
                         HWND_TOP,
                         0,  // 设置偏移量,把原来窗口的菜单遮住                
                         0,
                         tempRect.right - tempRect.left,// (int)this.Width,
                         tempRect.bottom - tempRect.top, // (int)this.Height,
                         SWP_FRAMECHANGED);
       }
 
       public static void KillProcessByName(string ProcName)
       {
           Process[] myProcesses = Process.GetProcessesByName(ProcName);
           foreach (Process myProcess in myProcesses)
           {
               //if (myProcess.MainWindowTitle.Length > 0)
               {
                   try
                   {
                       string buf = myProcess.MainModule.ModuleName;// .MainWindowTitle;
                       myProcess.Kill();
                   }
                   catch { }
               }
           }
       }
       #endregion
 
   }

沒有留言:

張貼留言