├── 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
--------------------------------------------------------------------------------