### 出現問題 最近要為一個沒有 API 的平台制作 Automation,搵過好多唔同既方法,最後發現 stackoverflow 竟然係因最多人推介用 `PowerShell` 來解決,在先前係用過 "按鍵精靈" 同埋 "AutoIT" 的經驗,既然今次又要做 Automation 就不如用啲未用過既方法來開始。 ### PowerShell 經過一陣子的研究發現,原來 `PowerShell` 都係需要引入 .dll 程式庫來實現一些原生的 window 功能,而今次我要實行的是模擬 Mouse 及 Keyboard 的動作,對 Web 介面進行 Automation。簡單的追可以通過 WinForms 去實行。 ```ps1 // 引入 System.Windows.Forms Add-Type -AssemblyName System.Windows.Forms ``` 然後可以通過直接寫入 C# 代碼到 PowerShell 中即時運行。 以下的代碼是引入了外部的 `user32.dll` 以實行對 Mouse 及 Keyboard 的模擬動作。 ```ps1 Add-Type -TypeDefinition @" using System; using System.Threading; using System.Runtime.InteropServices; /** * mouse class */ public class Mouse { // mouse action public const uint MOUSEEVENTF_LEFTDOWN = 0x02; public const uint MOUSEEVENTF_LEFTUP = 0x04; public const uint MOUSEEVENTF_RIGHTDOWN = 0x08; public const uint MOUSEEVENTF_RIGHTUP = 0x10; [DllImport("user32.dll")] public static extern bool GetCursorPos(out POINT lpPoint); [StructLayout(LayoutKind.Sequential)] public struct POINT { public int X; public int Y; } [DllImport("user32.dll")] public static extern bool SetCursorPos(int x, int y); [DllImport("user32.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall)] public static extern void mouse_event(uint dwFlags, uint dx, uint dy, uint cButtons, uint dwExtraInfo); } /** * keyboard class */ public class Keyboard { // keys public const byte VK_CONTROL = 0x11; public const byte VK_RETURN = 0x0D; public const byte VK_A = 0x41; public const byte VK_B = 0x42; public const byte VK_C = 0x43; public const byte VK_D = 0x44; public const byte VK_E = 0x45; public const byte VK_F = 0x46; public const byte VK_G = 0x47; public const byte VK_H = 0x48; public const byte VK_I = 0x49; public const byte VK_J = 0x4A; public const byte VK_K = 0x4B; public const byte VK_L = 0x4C; public const byte VK_M = 0x4D; public const byte VK_N = 0x4E; public const byte VK_O = 0x4F; public const byte VK_P = 0x50; public const byte VK_Q = 0x51; public const byte VK_R = 0x52; public const byte VK_S = 0x53; public const byte VK_T = 0x54; public const byte VK_U = 0x55; public const byte VK_V = 0x56; public const byte VK_W = 0x57; public const byte VK_X = 0x58; public const byte VK_Y = 0x59; public const byte VK_Z = 0x5A; // actions public const uint KEYEVENTF_KEYDOWN = 0x0000; public const uint KEYEVENTF_KEYUP = 0x0002; [DllImport("user32.dll")] public static extern void keybd_event(byte bVk, byte bScan, uint dwFlags, IntPtr dwExtraInfo); } "@ ``` 當引入完上面的代碼後,可以在下面自己加入你想要運行的代碼去呼叫引入的代碼。 ```ps1 // Mouse 左鍵按下 [Mouse]::mouse_event([Mouse]::MOUSEEVENTF_LEFTDOWN, 0, 0, 0, 0); // Mouuse 左鍵升起 [Mouse]::mouse_event([Mouse]::MOUSEEVENTF_LEFTUP, 0, 0, 0, 0); ``` 這樣就可以用 PowerShell 呼叫 C# 來逹成你想要的功能了,正因為呼叫的是 C#,所以是機乎所有的 Window 功能也可以通過 PowerShell 去運行,所以要運行 `.ps1` 的時候可能需要另外的權限。