使用C#制作可以录制自动化执行Windows操作脚本工具——类似于按键精灵 ...

打印 上一主题 下一主题

主题 876|帖子 876|积分 2628

我们知道,如果要对一个网站进行自动化测试,可以使用Python的selenium对获取网页的元素进行一系列操作。同样,对于Windows应用,可以使用C#或者AutoIt(也是一种脚本语言,相比较与C#,AutoIt更适合做Windows应用的自动化脚本)捕获窗体句柄进行操作。
今天主要记录一下使用WPF制作可以录制自动化执行Windows操作脚本工具,类似于按键精灵的录制脚本的操作。主要使用勾子捕获鼠标键盘事件。
  1. <Window x:Class="AutoOperationTool.MainWindow"
  2.         xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
  3.         xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
  4.         xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
  5.         xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
  6.         xmlns:local="clr-namespace:AutoOperationTool"
  7.         mc:Ignorable="d"
  8.         Title="自动化脚本" Height="450" Width="800">
  9.     <Grid>
  10.         <Grid.RowDefinitions>
  11.             <RowDefinition></RowDefinition>
  12.             <RowDefinition></RowDefinition>
  13.             <RowDefinition></RowDefinition>
  14.         </Grid.RowDefinitions>
  15.         <Grid VerticalAlignment="Bottom" Margin="0 0 0 30">
  16.             <Grid.ColumnDefinitions>
  17.                 <ColumnDefinition></ColumnDefinition>
  18.                 <ColumnDefinition></ColumnDefinition>
  19.             </Grid.ColumnDefinitions>
  20.             <Label Grid.Column="0" VerticalAlignment="Center" HorizontalAlignment="Right" Content="当前鼠标在屏幕的位置:"></Label>
  21.             <Grid Grid.Column="1" VerticalAlignment="Center" HorizontalAlignment="Left">
  22.                 <Grid.ColumnDefinitions>
  23.                     <ColumnDefinition></ColumnDefinition>
  24.                     <ColumnDefinition></ColumnDefinition>
  25.                 </Grid.ColumnDefinitions>
  26.                 <Grid Grid.Column="0">
  27.                     <Grid.ColumnDefinitions>
  28.                         <ColumnDefinition></ColumnDefinition>
  29.                         <ColumnDefinition></ColumnDefinition>
  30.                     </Grid.ColumnDefinitions>
  31.                     <Label  Content="X:"></Label>
  32.                     <TextBlock x:Name="xPoint" Grid.Column="1" HorizontalAlignment="Center" VerticalAlignment="Center"></TextBlock>
  33.                 </Grid>
  34.                 <Grid Grid.Column="1">
  35.                     <Grid.ColumnDefinitions>
  36.                         <ColumnDefinition></ColumnDefinition>
  37.                         <ColumnDefinition></ColumnDefinition>
  38.                     </Grid.ColumnDefinitions>
  39.                     <Label  Content="Y:"></Label>
  40.                     <TextBlock x:Name="yPoint" Grid.Column="1" HorizontalAlignment="Center" VerticalAlignment="Center"></TextBlock>
  41.                 </Grid>
  42.             </Grid>
  43.         </Grid>
  44.         <Grid Grid.Row="1">
  45.             <Grid.ColumnDefinitions>
  46.                 <ColumnDefinition></ColumnDefinition>
  47.                 <ColumnDefinition></ColumnDefinition>
  48.             </Grid.ColumnDefinitions>
  49.             <Grid Grid.Column="0">
  50.                 <Grid.ColumnDefinitions>
  51.                     <ColumnDefinition></ColumnDefinition>
  52.                     <ColumnDefinition></ColumnDefinition>
  53.                 </Grid.ColumnDefinitions>
  54.                 <Label Content="设置循环次数:" VerticalAlignment="Center" HorizontalAlignment="Right"></Label>
  55.                 <Border Grid.Column="1" Width="120" Height="35" BorderBrush="Black" HorizontalAlignment="Left" BorderThickness="1">
  56.                     <TextBox Width="120" Height="35" x:Name="txtCycleCount" Text="1" VerticalAlignment="Center" HorizontalAlignment="Center"></TextBox>
  57.                 </Border>
  58.             </Grid>
  59.             <Grid Grid.Column="2">
  60.                 <Grid.ColumnDefinitions>
  61.                     <ColumnDefinition></ColumnDefinition>
  62.                     <ColumnDefinition Width="320"></ColumnDefinition>
  63.                 </Grid.ColumnDefinitions>
  64.                 <Label Content="脚本路径:" VerticalAlignment="Center" HorizontalAlignment="Right"></Label>
  65.                 <Border Grid.Column="1" Width="310" Height="35" BorderBrush="Black" HorizontalAlignment="Left" BorderThickness="1">
  66.                     <TextBox Width="310" Height="35" x:Name="txtScriptPath" VerticalAlignment="Center" HorizontalAlignment="Center" TextWrapping="Wrap"></TextBox>
  67.                 </Border>
  68.             </Grid>
  69.         </Grid>
  70.         <Grid Grid.Row="2" Margin="0 30 0 0" VerticalAlignment="Top">
  71.             <Grid.ColumnDefinitions>
  72.                 <ColumnDefinition></ColumnDefinition>
  73.                 <ColumnDefinition></ColumnDefinition>
  74.                 <ColumnDefinition></ColumnDefinition>
  75.                 <ColumnDefinition></ColumnDefinition>
  76.             </Grid.ColumnDefinitions>
  77.             <Button Grid.Column="0" x:Name="btnStart" Width="100" Height="40" Content="开始录制" Click="Start_OnClick"></Button>
  78.             <Button Grid.Column="1" x:Name="btnEnd" Width="100" Height="40" Content="结束录制" Click="End_OnClick"></Button>
  79.             <Button Grid.Column="2" x:Name="btnExec" Width="100" Height="40" Content="执行脚本" Click="Exec_OnClick"></Button>
  80.             <Button Grid.Column="3" x:Name="btnCancel" Width="100" Height="40" Content="取消执行" Click="CancelExec_OnClick"></Button>
  81.         </Grid>
  82.     </Grid>
  83. </Window>
复制代码
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Configuration;
  4. using System.IO;
  5. using System.Linq;
  6. using System.Threading;
  7. using System.Threading.Tasks;
  8. using System.Windows;
  9. using Newtonsoft.Json;
  10. using Path = System.IO.Path;
  11. namespace AutoOperationTool
  12. {
  13.     /// <summary>
  14.     /// MainWindow.xaml 的交互逻辑
  15.     /// </summary>
  16.     public partial class MainWindow : Window
  17.     {
  18.         // 用于取消任务的执行
  19.         private CancellationTokenSource cancelTokenSource = new CancellationTokenSource();
  20.         private Task ExecTask { get; set; }
  21.         private KeyAction KeyAction { get; set; }
  22.         public MainWindow()
  23.         {
  24.             InitializeComponent();
  25.             Configuration config = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None);
  26.             txtScriptPath.Text = config.AppSettings.Settings["path"].Value;
  27.             KeyAction = new KeyAction();
  28.             btnEnd.IsEnabled = false;
  29.             btnCancel.IsEnabled = false;
  30.         }
  31.         private bool KMHook_MouseCallback(object arg)
  32.         {
  33.             if (arg is long[] arrs && arrs.Length == 3)
  34.             {
  35.                 var type = arrs[0];
  36.                 var x = arrs[1];
  37.                 var y = arrs[2];
  38.                 if (type == 1)
  39.                 {
  40.                     var model = new MouseOperation();
  41.                     model.MouseOperationType = MouseOperationTypeEnum.Click;
  42.                     model.Point = new Point(){ X = x, Y = y};
  43.                     model.Time = DateTime.Now;
  44.                     model.OperationType = OperationType.Mouse;
  45.                     PrintLog.WriteTxt.GetInstance().AppendInfoLog(JsonConvert.SerializeObject(model));
  46.                 }
  47.                 xPoint.Text = x.ToString();
  48.                 yPoint.Text = y.ToString();
  49.                 Console.WriteLine($"X:{x};Y:{y}");
  50.             }
  51.             return true;
  52.         }
  53.         private bool KMHook_KeyCallback(object arg)
  54.         {
  55.             if (arg is long[] arrs && arrs.Length == 3)
  56.             {
  57.                 var type = arrs[0];
  58.                 var code = arrs[1];
  59.                 var time = arrs[2];
  60.                 var model = new KeyOperation();
  61.                 if (type == 0)
  62.                 {
  63.                     model.KeyOperationType = KeyOperationTypeEnum.Press;
  64.                 }
  65.                 else if (type == 1)
  66.                 {
  67.                     model.KeyOperationType = KeyOperationTypeEnum.Up;
  68.                 }
  69.                 model.KeyCode = (Key)Enum.Parse(typeof(Key), code.ToString());
  70.                 model.OperationType = OperationType.Key;
  71.                 model.Time = DateTime.Now;
  72.                 PrintLog.WriteTxt.GetInstance().AppendInfoLog(JsonConvert.SerializeObject(model));
  73.             }
  74.             return true;
  75.         }
  76.         private void Start_OnClick(object sender, RoutedEventArgs e)
  77.         {
  78.             btnEnd.IsEnabled = true;
  79.             btnStart.IsEnabled = false;
  80.             btnExec.IsEnabled = false;
  81.             btnCancel.IsEnabled = false;
  82.             // 如果存在脚本名称,序号往前加
  83.             PrintLog.WriteTxt.GetInstance().FileLogName = "script1.txt";
  84.             var fileLogName = PrintLog.WriteTxt.GetInstance().FileLogName;
  85.             if (File.Exists(PrintLog.WriteTxt.GetInstance().FileStartupPath + PrintLog.WriteTxt.GetInstance().FileLogName))
  86.             {
  87.                 var fileName = PrintLog.WriteTxt.GetInstance().FileLogName;
  88.                 while (File.Exists(PrintLog.WriteTxt.GetInstance().FileStartupPath + fileName))
  89.                 {
  90.                     if (fileName.StartsWith("script") && fileName.EndsWith(".txt"))
  91.                     {
  92.                         var strCount = fileName.Replace("script", "").Replace(".txt", "");
  93.                         int count;
  94.                         if (int.TryParse(strCount, out count))
  95.                         {
  96.                             count++;
  97.                             fileName = $"script{count}.txt";
  98.                         }
  99.                     }
  100.                     else
  101.                     {
  102.                         Directory.Delete(PrintLog.WriteTxt.GetInstance().FileStartupPath + PrintLog.WriteTxt.GetInstance().FileLogName);
  103.                         break;
  104.                     }
  105.                 }
  106.                 fileLogName = fileName;
  107.             }
  108.             PrintLog.WriteTxt.GetInstance().FileLogName = fileLogName;
  109.             txtScriptPath.Text = Path.Combine(PrintLog.WriteTxt.GetInstance().FileStartupPath, fileLogName);
  110.             Configuration config = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None);
  111.             config.AppSettings.Settings["path"].Value = txtScriptPath.Text;
  112.             config.Save();
  113.             KMHook.MouseCallback += KMHook_MouseCallback;
  114.             KMHook.KeyCallback += KMHook_KeyCallback;
  115.             KMHook.InsertHook();
  116.         }
  117.         private void End_OnClick(object sender, RoutedEventArgs e)
  118.         {
  119.             KMHook.MouseCallback -= KMHook_MouseCallback;
  120.             KMHook.KeyCallback -= KMHook_KeyCallback;
  121.             KMHook.RemoveHook();
  122.             btnStart.IsEnabled = true;
  123.             btnEnd.IsEnabled = !btnStart.IsEnabled;
  124.             btnExec.IsEnabled = true;
  125.             btnCancel.IsEnabled = !btnExec.IsEnabled;
  126.         }
  127.         private void Exec_OnClick(object sender, RoutedEventArgs e)
  128.         {
  129.             btnStart.IsEnabled = false;
  130.             btnEnd.IsEnabled = !btnStart.IsEnabled;
  131.             btnExec.IsEnabled = false;
  132.             btnCancel.IsEnabled = !btnExec.IsEnabled;
  133.             var listOperations = new List<Operation>();
  134.             var path = txtScriptPath.Text;
  135.             var listStrs = File.ReadLines(path)?.ToList();
  136.             if (listStrs != null && listStrs.Count > 0)
  137.             {
  138.                 foreach (var strScript in listStrs)
  139.                 {
  140.                     try
  141.                     {
  142.                         var operation = JsonConvert.DeserializeObject<Operation>(strScript);
  143.                         if (operation.OperationType == OperationType.Mouse)
  144.                         {
  145.                             var mouseOperation = JsonConvert.DeserializeObject<MouseOperation>(strScript);
  146.                             listOperations.Add(mouseOperation);
  147.                         }
  148.                         else if (operation.OperationType == OperationType.Key)
  149.                         {
  150.                             var keyOperation = JsonConvert.DeserializeObject<KeyOperation>(strScript);
  151.                             listOperations.Add(keyOperation);
  152.                         }
  153.                     }
  154.                     catch (Exception ex)
  155.                     {
  156.                         throw ex;
  157.                     }
  158.                 }
  159.             }
  160.             int count;
  161.             if (int.TryParse(txtCycleCount.Text, out count))
  162.             {
  163.                 ExecTask = Task.Factory.StartNew(() =>
  164.                 {
  165.                     if (count < 1) count = 1;
  166.                     for (int i = 0; i < count; i++)
  167.                     {
  168.                         DateTime lastTime = new DateTime();
  169.                         DateTime nextTime = new DateTime();
  170.                         for (int j = 0; j < listOperations.Count; j++)
  171.                         {
  172.                             if (lastTime == new DateTime())
  173.                             {
  174.                                 lastTime = listOperations[j].Time;
  175.                                 Exec(listOperations, j);
  176.                             }
  177.                             else
  178.                             {
  179.                                 nextTime = listOperations[j].Time;
  180.                                 if (j > 0)
  181.                                 {
  182.                                     lastTime = listOperations[j - 1].Time;
  183.                                 }
  184.                                 Thread.Sleep(nextTime - lastTime);
  185.                                 Exec(listOperations, j);
  186.                             }
  187.                         }
  188.                         Thread.Sleep(1000);
  189.                     }
  190.                     Application.Current.Dispatcher.Invoke(() =>
  191.                     {
  192.                         btnStart.IsEnabled = true;
  193.                         btnEnd.IsEnabled = !btnStart.IsEnabled;
  194.                         btnExec.IsEnabled = true;
  195.                         btnCancel.IsEnabled = !btnExec.IsEnabled;
  196.                     });
  197.                 }, cancelTokenSource.Token);
  198.             }
  199.         }
  200.         private void Exec(List<Operation> listOperations, int j)
  201.         {
  202.             if (listOperations[j].OperationType == OperationType.Mouse)
  203.             {
  204.                 var mouse = listOperations[j] as MouseOperation;
  205.                 MouseAction.DoClick((int)mouse.Point.X, (int)mouse.Point.Y);
  206.             }
  207.             else if (listOperations[j].OperationType == OperationType.Key)
  208.             {
  209.                 var key = listOperations[j] as KeyOperation;
  210.                 if (key.KeyOperationType == KeyOperationTypeEnum.Press)
  211.                 {
  212.                     KeyAction.MykeyDown(key.KeyCode);
  213.                 }
  214.                 else if (key.KeyOperationType == KeyOperationTypeEnum.Up)
  215.                 {
  216.                     KeyAction.MykeyUp(key.KeyCode);
  217.                 }
  218.             }
  219.         }
  220.         private void CancelExec_OnClick(object sender, RoutedEventArgs e)
  221.         {
  222.             if (ExecTask != null)
  223.             {
  224.                 for (int i = 0; i < 3; i++)
  225.                 {
  226.                     try
  227.                     {
  228.                         cancelTokenSource.Cancel();
  229.                         if (cancelTokenSource.IsCancellationRequested)
  230.                         {
  231.                             cancelTokenSource = new CancellationTokenSource();
  232.                             ExecTask.Dispose();
  233.                             btnStart.IsEnabled = true;
  234.                             btnEnd.IsEnabled = !btnStart.IsEnabled;
  235.                             btnExec.IsEnabled = true;
  236.                             btnCancel.IsEnabled = !btnExec.IsEnabled;
  237.                             break;
  238.                         }
  239.                     }
  240.                     catch (Exception)
  241.                     {
  242.                     }
  243.                 }
  244.             }
  245.         }
  246.     }
  247. }
复制代码
勾子监听键盘鼠标事件
  1. using System;
  2. using System.Runtime.InteropServices;
  3. namespace AutoOperationTool
  4. {
  5.     public class KMHook
  6.     {
  7.         public static bool InsertHook()
  8.         {
  9.             bool iRet;
  10.             iRet = InsertKeyboardHook();
  11.             if (!iRet)
  12.             {
  13.                 return false;
  14.             }
  15.             iRet = InsertMouseHook();
  16.             if (!iRet)
  17.             {
  18.                 removeKeyboardHook();
  19.                 return false;
  20.             }
  21.             return true;
  22.         }
  23.         public static bool RemoveHook()
  24.         {
  25.             bool iRet;
  26.             iRet = removeKeyboardHook();
  27.             if (iRet)
  28.             {
  29.                 iRet = removeMouseHook();
  30.             }
  31.             return iRet;
  32.         }
  33.         public static event Func<object, bool> MouseCallback;
  34.         public static event Func<object, bool> KeyCallback;
  35.         internal struct Keyboard_LL_Hook_Data
  36.         {
  37.             public UInt32 vkCode;
  38.             public UInt32 scanCode;
  39.             public UInt32 flags;
  40.             public UInt32 time;
  41.             public IntPtr extraInfo;
  42.         }
  43.         internal struct Mouse_LL_Hook_Data
  44.         {
  45.             internal long yx;
  46.             internal readonly int mouseData;
  47.             internal readonly uint flags;
  48.             internal readonly uint time;
  49.             internal readonly IntPtr dwExtraInfo;
  50.         }
  51.         private static IntPtr pKeyboardHook = IntPtr.Zero;
  52.         private static IntPtr pMouseHook = IntPtr.Zero;
  53.         //钩子委托声明
  54.         public delegate int HookProc(int code, IntPtr wParam, IntPtr lParam);
  55.         private static HookProc keyboardHookProc;
  56.         private static HookProc mouseHookProc;
  57.         //安装钩子
  58.         [DllImport("user32.dll")]
  59.         public static extern IntPtr SetWindowsHookEx(int idHook, HookProc lpfn, IntPtr pInstance, int threadID);
  60.         //卸载钩子
  61.         [DllImport("user32.dll", CallingConvention = CallingConvention.StdCall)]
  62.         public static extern bool UnhookWindowsHookEx(IntPtr pHookHandle);
  63.         [DllImport("user32.dll")]
  64.         public static extern int CallNextHookEx(IntPtr hhk, int nCode, IntPtr wParam, IntPtr lParam); //parameter 'hhk' is ignored.
  65.         private static int keyboardHookCallback(int code, IntPtr wParam, IntPtr lParam)
  66.         {
  67.             if (code < 0)
  68.             {
  69.                 return CallNextHookEx(IntPtr.Zero, code, wParam, lParam);
  70.             }
  71.             Keyboard_LL_Hook_Data khd = (Keyboard_LL_Hook_Data)Marshal.PtrToStructure(lParam, typeof(Keyboard_LL_Hook_Data));
  72.             System.Diagnostics.Debug.WriteLine($"key event:{wParam}, key code:{khd.vkCode}, event time:{khd.time}");
  73.             var keyType = 0L;
  74.             var iWParam = (int)wParam;
  75.             if (iWParam == 256)
  76.             {
  77.                 keyType = 0;
  78.             }
  79.             else if (iWParam == 257)
  80.             {
  81.                 keyType = 1;
  82.             }
  83.             else
  84.             {
  85.                 keyType = 0;
  86.             }
  87.             KeyCallback?.Invoke(new long[3] { keyType, (int)khd.vkCode, (int)khd.time });
  88.             return 0;
  89.         }
  90.         private static int mouseHookCallback(int code, IntPtr wParam, IntPtr lParam)
  91.         {
  92.             if (code < 0)
  93.             {
  94.                 return CallNextHookEx(IntPtr.Zero, code, wParam, lParam);
  95.             }
  96.             Mouse_LL_Hook_Data mhd = (Mouse_LL_Hook_Data)Marshal.PtrToStructure(lParam, typeof(Mouse_LL_Hook_Data));
  97.             System.Diagnostics.Debug.WriteLine($"mouse event:{wParam}, ({mhd.yx & 0xffffffff},{mhd.yx >> 32})");
  98.             var mouseType = 0L;
  99.             var iWParam = (int)wParam;
  100.             if (iWParam == 513)
  101.             {
  102.                 mouseType = 1;
  103.             }
  104.             else if (iWParam == 514)
  105.             {
  106.                 mouseType = 2;
  107.             }
  108.             else
  109.             {
  110.                 mouseType = 0;
  111.             }
  112.             MouseCallback?.Invoke(new long[3]{ mouseType , mhd.yx & 0xffffffff, mhd.yx >> 32 });
  113.             return 0;
  114.         }
  115.         //安装钩子方法
  116.         private static bool InsertKeyboardHook()
  117.         {
  118.             if (pKeyboardHook == IntPtr.Zero)//不存在钩子时
  119.             {
  120.                 //创建钩子
  121.                 keyboardHookProc = keyboardHookCallback;
  122.                 pKeyboardHook = SetWindowsHookEx(13, //13表示全局键盘事件。
  123.                     keyboardHookProc,
  124.                     (IntPtr)0,
  125.                     0);
  126.                 if (pKeyboardHook == IntPtr.Zero)//如果安装钩子失败
  127.                 {
  128.                     removeKeyboardHook();
  129.                     return false;
  130.                 }
  131.             }
  132.             return true;
  133.         }
  134.         private static bool InsertMouseHook()
  135.         {
  136.             if (pMouseHook == IntPtr.Zero)
  137.             {
  138.                 mouseHookProc = mouseHookCallback;
  139.                 pMouseHook = SetWindowsHookEx(14, //14表示全局鼠标事件
  140.                     mouseHookProc,
  141.                     (IntPtr)0,
  142.                     0);
  143.                 if (pMouseHook == IntPtr.Zero)
  144.                 {
  145.                     removeMouseHook();
  146.                     return false;
  147.                 }
  148.             }
  149.             return true;
  150.         }
  151.         private static bool removeKeyboardHook()
  152.         {
  153.             if (pKeyboardHook != IntPtr.Zero)
  154.             {
  155.                 if (UnhookWindowsHookEx(pKeyboardHook))
  156.                 {
  157.                     pKeyboardHook = IntPtr.Zero;
  158.                 }
  159.                 else
  160.                 {
  161.                     return false;
  162.                 }
  163.             }
  164.             return true;
  165.         }
  166.         private static bool removeMouseHook()
  167.         {
  168.             if (pMouseHook != IntPtr.Zero)
  169.             {
  170.                 if (UnhookWindowsHookEx(pMouseHook))
  171.                 {
  172.                     pMouseHook = IntPtr.Zero;
  173.                 }
  174.                 else
  175.                 {
  176.                     return false;
  177.                 }
  178.             }
  179.             return true;
  180.         }
  181.     }
  182. }
复制代码
操作键盘按键
  1. using System;
  2. using System.Runtime.InteropServices;
  3. namespace AutoOperationTool
  4. {
  5.     public class KeyAction
  6.     {
  7.         [DllImport("user32.dll", SetLastError = true)]
  8.         public static extern void keybd_event(byte bVk, byte bScan, uint dwFlags, UIntPtr dwExtraInfo);
  9.         /// key down
  10.         public void MykeyDown(Key vKeyCoad)
  11.         {
  12.             PressKey(vKeyCoad, false);
  13.         }
  14.         /// Key up
  15.         public void MykeyUp(Key vKeyCoad)
  16.         {
  17.             PressKey(vKeyCoad, true);
  18.         }
  19.         private void PressKey(Key key, bool up)
  20.         {
  21.             const int KEYEVENTF_EXTENDEDKEY = 0x1;
  22.             const int KEYEVENTF_KEYUP = 0x2;
  23.             if (up)
  24.             {
  25.                 keybd_event((byte)key, 0x45, KEYEVENTF_EXTENDEDKEY | KEYEVENTF_KEYUP, (UIntPtr)0);
  26.             }
  27.             else
  28.             {
  29.                 keybd_event((byte)key, 0x45, KEYEVENTF_EXTENDEDKEY, (UIntPtr)0);
  30.             }
  31.         }
  32.     }
  33. }
复制代码
操作鼠标移动及单击
  1. using System.Runtime.InteropServices;
  2. namespace AutoOperationTool
  3. {
  4.     public class MouseAction
  5.     {
  6.         [DllImport("user32")]
  7.         public static extern int mouse_event(int dwFlags, int dx, int dy, int cButtons, int dwExtraInfo);
  8.         [DllImport("User32.dll")]
  9.         public static extern bool SetCursorPos(int X, int Y);
  10.         public static void DoClick(int x, int y)
  11.         {
  12.             SetCursorPos(x, y);
  13.             mouse_event((int)MouseType.MOUSEEVENTF_LEFTDOWN | (int)MouseType.MOUSEEVENTF_LEFTUP, 0, 0, 0, 0);
  14.         }
  15.     }
  16. }
复制代码
 

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

欢乐狗

金牌会员
这个人很懒什么都没写!

标签云

快速回复 返回顶部 返回列表