├── Ghub64.dll ├── Ghub86.dll ├── MouseControl.dll ├── README.md ├── ghub_device.dll ├── lghub_installer - 2020.1.31550.0.exe.7z ├── lghub_installer - 2021.3.5164.0 - 2021.3.9205.exe.7z ├── lghub_installer - 2021.9.7463.0 - 2021.11.1775.exe.7z └── logitech.driver.dll /Ghub64.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ChengWeiJian03/MouseControl/6f37cae93c45aab5ae93e8b75b40d2e488daff1d/Ghub64.dll -------------------------------------------------------------------------------- /Ghub86.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ChengWeiJian03/MouseControl/6f37cae93c45aab5ae93e8b75b40d2e488daff1d/Ghub86.dll -------------------------------------------------------------------------------- /MouseControl.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ChengWeiJian03/MouseControl/6f37cae93c45aab5ae93e8b75b40d2e488daff1d/MouseControl.dll -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # 鼠标调用说明 2 | **此为借助dll文件来调用罗技鼠标驱动,以实现驱动级的键鼠调用** 3 |

4 | **注:MouseControl无水印且不依赖于罗技驱动,其他有水印并且依赖于罗技驱动** 5 | 6 | **原理解释:这些dll之所以能调用键鼠,是因为以前的罗技鼠标有漏洞,可以利用漏洞调用罗技的驱动,已实现驱动级的调用,罗技漏洞项目地址:https://github.com/ekknod/logitech-cve 可以根据项目自己编写代码** 7 | 8 | 最近收集到了一种调用雷蛇鼠标驱动的方法,测试完成后会更新到项目中,可以在issues催更(笑) 9 | 10 | ### 使用说明 11 | - 驱动:在使用前请安装老版的罗技驱动,即项目文件中的罗技驱动,如安装了新版本的罗技驱动,先卸载干净再安装老版驱动 12 | 13 | - 使用前设置:在使用前必须在鼠标设置里,将提高鼠标精度按钮点掉,处于未选中状态,并且将鼠标灵敏度调到正中间,不然鼠标在移动会有偏移 14 | 15 | - 使用:每个文件完成的键鼠移动都会有误差,每个单位移动的误差大概在0.2-0.3左右,积累起来还是挺大的,如想鼠标到达预定位置建议配合pid控制,示例见文尾 16 | 17 | - 芜湖~写了个LADRC控制鼠标移动,虽然不好用,但勉强用用.也在文尾,我甚至贴心的给了可视化调参 18 |

19 | 20 | **Python使用DLL文件示例** 21 | 22 | ```Python 23 | driver = ctypes.CDLL(r'.\MouseControl.dll') 24 | ``` 25 | ### DLL文件使用示例 26 | 27 | **MouseControl.dll调用示例** 28 | 29 | ```C++ 30 | // 相对移动 31 | move_R(int x, int y); 32 | // 绝对移动 33 | move_Abs(int x, int y); 34 | 35 | // 左键按下 36 | click_Left_down(); 37 | // 左键松开 38 | click_Left_up(); 39 | 40 | // 右键按下 41 | click_Right_down(); 42 | // 右键松开 43 | click_Right_up(); 44 | ``` 45 | 46 | **MouseControl.dll平滑移动示例** 47 | 48 | ```Python 49 | import time 50 | import pyautogui 51 | def linear_interpolation( x_end, y_end, num_steps, delay):# 绝对平滑移动 52 | start_x, start_y = pyautogui.position() 53 | dx = (x_end - start_x) / num_steps 54 | dy = (y_end - start_y) / num_steps 55 | 56 | for i in range(1,num_steps+1): 57 | next_x = int(start_x + dx * i) 58 | next_y = int(start_y + dy * i) 59 | 60 | driver.move_Abs(int(next_x), int(next_y)) 61 | 62 | time.sleep(delay) 63 | 64 | time.sleep(2) 65 | x_end = 30 66 | y_end = 30 67 | root = os.path.abspath(os.path.dirname(__file__)) 68 | driver = ctypes.CDLL(r'E:\yolov5-master\MouseControl.dll') 69 | linear_interpolation(x_end, y_end, num_steps=20, delay=0.01) 70 | ``` 71 | 72 | ```Python 73 | def r_linear_interpolation(r_x,r_y,num_steps,delay): 74 | r_y = 0-r_y 75 | dx = r_x/num_steps 76 | dy = r_y/num_steps 77 | for i in range(1,num_steps+1): 78 | next_x,next_y = (dx),(dy) 79 | driver.move_R(int(next_x),int(next_y)) 80 | time.sleep(delay) 81 | ``` 82 | 83 | **ghub_device.dll调用示例** 84 | 85 | ```Python 86 | from ctypes import CDLL 87 | 88 | try: 89 | gm = CDLL(r'./ghub_device.dll') 90 | gmok = gm.device_open() == 1 91 | if not gmok: 92 | print('未安装ghub或者lgs驱动!!!') 93 | else: 94 | print('初始化成功!') 95 | except FileNotFoundError: 96 | print('缺少文件') 97 | 98 | #按下鼠标按键 99 | def press_mouse_button(button): 100 | if gmok: 101 | gm.mouse_down(button) 102 | 103 | #松开鼠标按键 104 | def release_mouse_button(button): 105 | if gmok: 106 | gm.mouse_up(button) 107 | 108 | #点击鼠标 109 | def click_mouse_button(button): 110 | press_mouse_button(button) 111 | release_mouse_button(button) 112 | 113 | #按下键盘按键 114 | def press_key(code): 115 | if gmok: 116 | gm.key_down(code) 117 | 118 | #松开键盘按键 119 | def release_key(code): 120 | if gmok: 121 | gm.key_up(code) 122 | 123 | #点击键盘按键 124 | def click_key(code): 125 | press_key(code) 126 | release_key(code) 127 | 128 | # 鼠标移动 129 | def mouse_xy(x, y, abs_move = False): 130 | if gmok: 131 | gm.moveR(int(x), int(y), abs_move) 132 | ``` 133 | 134 | **logitech.driver.dll调用示例** 135 | 136 | ```Python 137 | import ctypes 138 | import os 139 | import pynput 140 | import winsound 141 | 142 | try: 143 | root = os.path.abspath(os.path.dirname(__file__)) 144 | driver = ctypes.CDLL(f'{root}/logitech.driver.dll') 145 | ok = driver.device_open() == 1 # 该驱动每个进程可打开一个实例 146 | if not ok: 147 | print('Error, GHUB or LGS driver not found') 148 | except FileNotFoundError: 149 | print(f'Error, DLL file not found') 150 | 151 | 152 | class Logitech: 153 | 154 | class mouse: 155 | 156 | """ 157 | code: 1:左键, 2:中键, 3:右键 158 | """ 159 | 160 | @staticmethod 161 | def press(code): 162 | if not ok: 163 | return 164 | driver.mouse_down(code) 165 | 166 | @staticmethod 167 | def release(code): 168 | if not ok: 169 | return 170 | driver.mouse_up(code) 171 | 172 | @staticmethod 173 | def click(code): 174 | if not ok: 175 | return 176 | driver.mouse_down(code) 177 | driver.mouse_up(code) 178 | 179 | @staticmethod 180 | def scroll(a): 181 | """ 182 | a:没搞明白 183 | """ 184 | if not ok: 185 | return 186 | driver.scroll(a) 187 | 188 | @staticmethod 189 | def move(x, y): 190 | """ 191 | 相对移动, 绝对移动需配合 pywin32 的 win32gui 中的 GetCursorPos 计算位置 192 | pip install pywin32 -i https://pypi.tuna.tsinghua.edu.cn/simple 193 | x: 水平移动的方向和距离, 正数向右, 负数向左 194 | y: 垂直移动的方向和距离 195 | """ 196 | if not ok: 197 | return 198 | if x == 0 and y == 0: 199 | return 200 | driver.moveR(x, y, False) 201 | 202 | class keyboard: 203 | 204 | """ 205 | 键盘按键函数中,传入的参数采用的是键盘按键对应的键码 206 | code: 'a'-'z':A键-Z键, '0'-'9':0-9, 其他的没猜出来 207 | """ 208 | 209 | @staticmethod 210 | def press(code): 211 | 212 | if not ok: 213 | return 214 | driver.key_down(code) 215 | 216 | @staticmethod 217 | def release(code): 218 | if not ok: 219 | return 220 | driver.key_up(code) 221 | 222 | @staticmethod 223 | def click(code): 224 | if not ok: 225 | return 226 | driver.key_down(code) 227 | driver.key_up(code) 228 | 229 | 230 | if __name__ == '__main__': # 测试 231 | 232 | winsound.Beep(800, 200) 233 | 234 | def release(key): 235 | if key == pynput.keyboard.Key.end: # 结束程序 End 键 236 | winsound.Beep(400, 200) 237 | return False 238 | elif key == pynput.keyboard.Key.home: # 移动鼠标 Home 键 239 | winsound.Beep(600, 200) 240 | Logitech.mouse.move(100, 100) 241 | 242 | with pynput.keyboard.Listener(on_release=release) as k: 243 | k.join() 244 | 245 | ``` 246 | 247 | **Ghub.dll导出函数** 248 | 249 | ```C++ 250 | BOOL INIT() //初始化ghub 251 | void MoveR(int x, int y) //相對移動 252 | void FREE() //釋放 253 | ``` 254 | 255 | **PID控制鼠标移动** 256 | ```Python 257 | # Encoding: utf-8 258 | from simple_pid import PID 259 | import ctypes 260 | import pynput 261 | import pyautogui 262 | def mouse_move(driver,target_x,target_y): 263 | mouse = pynput.mouse.Controller() 264 | while True: 265 | if abs(target_x - mouse.position[0])<3 and abs(target_y - mouse.position[1])<3: 266 | break 267 | pid_x = PID(0.25, 0.01, 0.01, setpoint=target_x) 268 | pid_y = PID(0.25, 0.01, 0.01, setpoint=target_y) 269 | next_x,next_y = pid_x(mouse.position[0]),pid_y(mouse.position[1]) 270 | driver.moveR(int(round(next_x)), int(round(next_y)), False) # 鼠标移动 271 | # print(mouse.position) # 打印鼠标位置 272 | 273 | if __name__ == '__main__': 274 | driver = ctypes.CDLL(f'./logitech.driver.dll') 275 | while 1: 276 | mouse_move(driver,800,900) 277 | error = pyautogui.position() # 这里摆个这个pyautogui.position(),是因为pynput好像是有点玄学bug,目标y值超过900鼠标就会挪不过去,但此时只要用一下pyautogui.position(),问题就解决了 278 | 279 | ``` 280 | 281 | **LADRC控制鼠标移动** 282 | ```Python 283 | import streamlit as st 284 | import matplotlib.pyplot as plt 285 | import numpy as np 286 | from functools import partial 287 | from math import factorial 288 | import pyautogui 289 | import time 290 | 291 | from matplotlib import rcParams 292 | 293 | 294 | class LADRC: 295 | def __init__(self, 296 | ordenProceso: int, 297 | gananciaNominal: float, 298 | anchoBandaControlador: float, 299 | anchoBandaLESO: float, 300 | condicionInicial: int 301 | ) -> None: 302 | self.u = 0 303 | self.h = 0.001 304 | 305 | self.nx = int(ordenProceso) 306 | self.bo = gananciaNominal 307 | self.wc = anchoBandaControlador 308 | self.wo = anchoBandaLESO 309 | self.zo = condicionInicial 310 | 311 | self.Cg, self.Ac, self.Bc, self.Cc, self.zo, self.L, self.K, self.z = self.ConstruirMatrices() 312 | 313 | def ConstruirMatrices(self) -> tuple: 314 | n = self.nx + 1 315 | 316 | K = np.zeros([1, self.nx]) 317 | for i in range(self.nx): 318 | K[0, i] = pow(self.wc, n - (i + 1)) * ( 319 | (factorial(self.nx)) / (factorial((i + 1) - 1) * factorial(n - (i + 1)))) 320 | 321 | L = np.zeros([n, 1]) 322 | for i in range(n): 323 | L[i] = pow(self.wo, i + 1) * ( 324 | (factorial(n)) / (factorial(i + 1) * factorial(n - (i + 1)))) 325 | 326 | Cg = self.bo 327 | 328 | Ac = np.vstack((np.hstack((np.zeros([n - 1, 1]), np.identity(n - 1))), np.zeros([1, n]))) 329 | Bc = np.vstack((np.zeros([self.nx - 1, 1]), self.bo, 0)) 330 | Cc = np.hstack(([[1]], np.zeros([1, n - 1]))) 331 | zo = np.vstack(([[self.zo]], np.zeros([n - 1, 1]))) 332 | z = np.zeros([n, 1]) 333 | 334 | return Cg, Ac, Bc, Cc, zo, L, K, z 335 | 336 | def LESO(self, u, y, z) -> np.ndarray: 337 | return np.matmul(self.Ac, z) + self.Bc * u + self.L * (y - np.matmul(self.Cc, z)) 338 | 339 | def Runkut4(self, F, z, h): 340 | k0 = h * F(z) 341 | k1 = h * F(z + 0.5 * k0) 342 | k2 = h * F(z + 0.5 * k1) 343 | k3 = h * F(z + k2) 344 | return z + (1 / 6) * (k0 + 2 * k1 + 2 * k2 + k3) 345 | 346 | def SalidaControl(self, r: int, y: int): 347 | leso = partial(self.LESO, self.u, y) 348 | self.z = self.Runkut4(leso, self.z, self.h) 349 | u0 = self.K[0, 0] * (r - self.z[0, 0]) 350 | for i in range(self.nx - 1): 351 | u0 -= self.K[0, i + 1] * self.z[i + 1, 0] 352 | 353 | return (u0 - self.z[self.nx, 0]) * self.Cg 354 | 355 | 356 | def control_movimiento_raton(x_objetivo, y_objetivo, wc, wo, bo): 357 | controlador = LADRC(ordenProceso=2, gananciaNominal=bo, anchoBandaControlador=wc, anchoBandaLESO=wo, 358 | condicionInicial=0) 359 | trajectory = [] 360 | move_attempts = 0 361 | max_attempts = 50 362 | 363 | while move_attempts < max_attempts: 364 | x_actual, y_actual = pyautogui.position() 365 | trajectory.append((x_actual, y_actual)) 366 | error_x = x_objetivo - x_actual 367 | error_y = y_objetivo - y_actual 368 | 369 | if abs(error_x) < 5 and abs(error_y) < 5: 370 | st.write("移动成功") 371 | break 372 | 373 | u_x = controlador.SalidaControl(error_x, x_actual) 374 | u_y = controlador.SalidaControl(error_y, y_actual) 375 | 376 | # Debug outputs 377 | # st.write(f"Attempt: {move_attempts}") 378 | # st.write(f"Current Position: ({x_actual}, {y_actual})") 379 | # st.write(f"Control Output: ({u_x}, {u_y})") 380 | # st.write(f"Errors: ({error_x}, {error_y})") 381 | 382 | pyautogui.moveRel(int(u_x), int(u_y)) 383 | time.sleep(0.01) 384 | move_attempts += 1 385 | 386 | # Final check for success 387 | x_final, y_final = pyautogui.position() 388 | if abs(x_final - x_objetivo) < 5 and abs(y_final - y_objetivo) < 5: 389 | st.write("移动成功") 390 | else: 391 | st.write("移动失败") 392 | 393 | return trajectory 394 | 395 | 396 | # Streamlit 代码 397 | st.title("LADRC 控制鼠标移动调参") 398 | 399 | x_target = st.slider("目标位置 X", 0, 1920, 500) 400 | y_target = st.slider("目标位置 Y", 0, 1080, 500) 401 | wc = st.slider("控制器带宽 (wc)", 0.1, 5.0, 1.0) 402 | wo = st.slider("LESO 带宽 (wo)", 0.1, 5.0, 1.0) 403 | bo = st.slider("增益 (bo)", 0.1, 2.0, 0.7) 404 | 405 | if st.button("开始控制"): 406 | trajectory = control_movimiento_raton(x_target, y_target, wc, wo, bo) 407 | 408 | # 绘制鼠标移动轨迹 409 | x_values = [point[0] for point in trajectory] 410 | y_values = [point[1] for point in trajectory] 411 | rcParams['font.family'] = ['SimHei'] 412 | rcParams['axes.unicode_minus'] = False 413 | 414 | plt.figure(figsize=(10, 6)) 415 | 416 | plt.scatter(x_values[0], y_values[0], color='g', label='起点') 417 | plt.scatter(x_values[-1], y_values[-1], color='r', label='终点') 418 | plt.scatter(x_target, y_target, color='purple', label='目标点') 419 | plt.plot(x_values, y_values, marker='o', linestyle='-', color='b') 420 | plt.xlim(0, 1920) 421 | plt.ylim(0, 1080) 422 | plt.gca().invert_yaxis() 423 | plt.xlabel('X Position') 424 | plt.ylabel('Y Position') 425 | plt.title('Mouse Movement Trajectory') 426 | plt.legend() 427 | st.pyplot(plt) 428 | 429 | ``` 430 | -------------------------------------------------------------------------------- /ghub_device.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ChengWeiJian03/MouseControl/6f37cae93c45aab5ae93e8b75b40d2e488daff1d/ghub_device.dll -------------------------------------------------------------------------------- /lghub_installer - 2020.1.31550.0.exe.7z: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ChengWeiJian03/MouseControl/6f37cae93c45aab5ae93e8b75b40d2e488daff1d/lghub_installer - 2020.1.31550.0.exe.7z -------------------------------------------------------------------------------- /lghub_installer - 2021.3.5164.0 - 2021.3.9205.exe.7z: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ChengWeiJian03/MouseControl/6f37cae93c45aab5ae93e8b75b40d2e488daff1d/lghub_installer - 2021.3.5164.0 - 2021.3.9205.exe.7z -------------------------------------------------------------------------------- /lghub_installer - 2021.9.7463.0 - 2021.11.1775.exe.7z: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ChengWeiJian03/MouseControl/6f37cae93c45aab5ae93e8b75b40d2e488daff1d/lghub_installer - 2021.9.7463.0 - 2021.11.1775.exe.7z -------------------------------------------------------------------------------- /logitech.driver.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ChengWeiJian03/MouseControl/6f37cae93c45aab5ae93e8b75b40d2e488daff1d/logitech.driver.dll --------------------------------------------------------------------------------