Windows 服务程序实现鼠标模拟

```cpp

#include <windows.h>

#include <fstream>

#include <string>

#include <tchar.h>

#include <thread>

#include <vector>

#define SERVICE_NAME _T("MouseSimulationService")

// 全局变量

SERVICE_STATUS g_ServiceStatus = { 0 };

SERVICE_STATUS_HANDLE g_StatusHandle = NULL;

HANDLE g_ServiceStopEvent = INVALID_HANDLE_VALUE;

// 日志类

class Logger {

private:

std::ofstream logFile;

public:

Logger(const std::string& filename) {

logFile.open(filename, std::ios::app);

}

void Log(const std::string& message) {

if (logFile.is_open()) {

SYSTEMTIME st;

GetLocalTime(&st);

logFile << st.wYear << "-" << st.wMonth << "-" << st.wDay << " "

<< st.wHour << ":" << st.wMinute << ":" << st.wSecond << " - "

<< message << std::endl;

logFile.flush();

}

}

~Logger() {

if (logFile.is_open()) {

logFile.close();

}

}

};

// 全局日志对象

Logger* g_Logger = nullptr;

// 鼠标模拟类

class MouseSimulator {

public:

static bool MoveTo(int x, int y) {

// 获取桌面窗口的句柄

HWND desktopHwnd = GetDesktopWindow();

if (!desktopHwnd) {

if (g_Logger) g_Logger->Log("Failed to get desktop window handle");

return false;

}

// 获取输入桌面

HDESK hDesk = OpenInputDesktop(0, FALSE, DESKTOP_CREATEMENU | DESKTOP_CREATEWINDOW |

DESKTOP_ENUMERATE | DESKTOP_HOOKCONTROL | DESKTOP_WRITEOBJECTS | DESKTOP_READOBJECTS |

DESKTOP_SWITCHDESKTOP | GENERIC_WRITE);

if (!hDesk) {

if (g_Logger) g_Logger->Log("Failed to open input desktop");

return false;

}

// 设置线程桌面

if (!SetThreadDesktop(hDesk)) {

if (g_Logger) g_Logger->Log("Failed to set thread desktop");

CloseDesktop(hDesk);

return false;

}

// 计算绝对坐标

double screenWidth = GetSystemMetrics(SM_CXSCREEN) - 1;

double screenHeight = GetSystemMetrics(SM_CYSCREEN) - 1;

double dx = x * (65535.0f / screenWidth);

double dy = y * (65535.0f / screenHeight);

INPUT input = { 0 };

input.type = INPUT_MOUSE;

input.mi.dwFlags = MOUSEEVENTF_ABSOLUTE | MOUSEEVENTF_VIRTUALDESK | MOUSEEVENTF_MOVE;

input.mi.dx = static_cast<LONG>(dx);

input.mi.dy = static_cast<LONG>(dy);

UINT result = SendInput(1, &input, sizeof(INPUT));

CloseDesktop(hDesk);

if (result != 1) {

if (g_Logger) g_Logger->Log("Failed to move mouse");

return false;

}

if (g_Logger) g_Logger->Log("Mouse moved to " + std::to_string(x) + "," + std::to_string(y));

return true;

}

static bool Click() {

INPUT inputs[2] = { 0 };

inputs[0].type = INPUT_MOUSE;

inputs[0].mi.dwFlags = MOUSEEVENTF_LEFTDOWN;

inputs[1].type = INPUT_MOUSE;

inputs[1].mi.dwFlags = MOUSEEVENTF_LEFTUP;

UINT result = SendInput(2, inputs, sizeof(INPUT));

if (result != 2) {

if (g_Logger) g_Logger->Log("Failed to perform click");

return false;

}

if (g_Logger) g_Logger->Log("Click performed");

return true;

}

};

// 命名管道处理类

class PipeHandler {

private:

static const int BUFFER_SIZE = 1024;

HANDLE pipe;

public:

PipeHandler() : pipe(INVALID_HANDLE_VALUE) {}

bool Create() {

pipe = CreateNamedPipe(

TEXT("\\\\.\\pipe\\MouseSimulationPipe"),

PIPE_ACCESS_DUPLEX,

PIPE_TYPE_MESSAGE | PIPE_READMODE_MESSAGE | PIPE_WAIT,

PIPE_UNLIMITED_INSTANCES,

BUFFER_SIZE,

BUFFER_SIZE,

0,

NULL);

if (pipe == INVALID_HANDLE_VALUE) {

if (g_Logger) g_Logger->Log("Failed to create pipe");

return false;

}

return true;

}

bool WaitForConnection() {

if (!ConnectNamedPipe(pipe, NULL)) {

if (GetLastError() != ERROR_PIPE_CONNECTED) {

if (g_Logger) g_Logger->Log("Failed to connect to pipe");

return false;

}

}

return true;

}

bool ReadCommand(std::string& command) {

char buffer[BUFFER_SIZE];

DWORD bytesRead;

if (ReadFile(pipe, buffer, BUFFER_SIZE, &bytesRead, NULL)) {

buffer[bytesRead] = '\0';

command = std::string(buffer);

return true;

}

return false;

}

void Close() {

if (pipe != INVALID_HANDLE_VALUE) {

DisconnectNamedPipe(pipe);

CloseHandle(pipe);

pipe = INVALID_HANDLE_VALUE;

}

}

~PipeHandler() {

Close();

}

};

// 服务控制处理函数

VOID WINAPI ServiceCtrlHandler(DWORD CtrlCode)

{

switch (CtrlCode)

{

case SERVICE_CONTROL_STOP:

if (g_ServiceStatus.dwCurrentState != SERVICE_RUNNING)

break;

g_ServiceStatus.dwControlsAccepted = 0;

g_ServiceStatus.dwCurrentState = SERVICE_STOP_PENDING;

g_ServiceStatus.dwWin32ExitCode = 0;

g_ServiceStatus.dwCheckPoint = 4;

SetServiceStatus(g_StatusHandle, &g_ServiceStatus);

SetEvent(g_ServiceStopEvent);

break;

default:

break;

}

}

// 解析命令

void ProcessCommand(const std::string& cmd) {

try {

size_t pos = cmd.find(' ');

if (pos == std::string::npos) return;

std::string action = cmd.substr(0, pos);

std::string coords = cmd.substr(pos + 1);

if (action == "move") {

pos = coords.find(',');

if (pos != std::string::npos) {

int x = std::stoi(coords.substr(0, pos));

int y = std::stoi(coords.substr(pos + 1));

MouseSimulator::MoveTo(x, y);

}

}

else if (action == "click") {

MouseSimulator::Click();

}

}

catch (const std::exception& e) {

if (g_Logger) g_Logger->Log("Error processing command: " + std::string(e.what()));

}

}

// 服务主函数

VOID WINAPI ServiceMain(DWORD argc, LPTSTR* argv)

{

g_StatusHandle = RegisterServiceCtrlHandler(SERVICE_NAME, ServiceCtrlHandler);

if (g_StatusHandle == NULL) return;

g_ServiceStatus.dwServiceType = SERVICE_WIN32_OWN_PROCESS;

g_ServiceStatus.dwCurrentState = SERVICE_START_PENDING;

g_ServiceStatus.dwControlsAccepted = SERVICE_ACCEPT_STOP;

g_ServiceStatus.dwWin32ExitCode = 0;

g_ServiceStatus.dwServiceSpecificExitCode = 0;

g_ServiceStatus.dwCheckPoint = 0;

// 初始化日志

g_Logger = new Logger("C:\\MouseService.log");

g_Logger->Log("Service starting...");

// 创建停止事件

g_ServiceStopEvent = CreateEvent(NULL, TRUE, FALSE, NULL);

if (g_ServiceStopEvent == NULL)

{

g_ServiceStatus.dwCurrentState = SERVICE_STOPPED;

g_ServiceStatus.dwWin32ExitCode = GetLastError();

SetServiceStatus(g_StatusHandle, &g_ServiceStatus);

return;

}

// 服务已启动

g_ServiceStatus.dwCurrentState = SERVICE_RUNNING;

g_ServiceStatus.dwCheckPoint = 0;

g_ServiceStatus.dwWaitHint = 0;

SetServiceStatus(g_StatusHandle, &g_ServiceStatus);

// 主服务循环

PipeHandler pipe;

while (true)

{

if (WaitForSingleObject(g_ServiceStopEvent, 0) == WAIT_OBJECT_0)

break;

if (pipe.Create())

{

if (pipe.WaitForConnection())

{

std::string command;

if (pipe.ReadCommand(command))

{

g_Logger->Log("Received command: " + command);

ProcessCommand(command);

}

}

pipe.Close();

}

}

// 清理

if (g_ServiceStopEvent)

{

CloseHandle(g_ServiceStopEvent);

g_ServiceStopEvent = NULL;

}

delete g_Logger;

g_Logger = nullptr;

g_ServiceStatus.dwCurrentState = SERVICE_STOPPED;

g_ServiceStatus.dwCheckPoint = 0;

g_ServiceStatus.dwWaitHint = 0;

SetServiceStatus(g_StatusHandle, &g_ServiceStatus);

}

// 主函数

int main()

{

SERVICE_TABLE_ENTRY ServiceTable[] =

{

{ SERVICE_NAME, (LPSERVICE_MAIN_FUNCTION)ServiceMain },

{ NULL, NULL }

};

if (!StartServiceCtrlDispatcher(ServiceTable))

{

return GetLastError();

}

return 0;

}

```

**测试客户端程序**:

```cpp

#include <windows.h>

#include <iostream>

#include <string>

int main()

{

while (true)

{

HANDLE hPipe = CreateFile(

TEXT("\\\\.\\pipe\\MouseSimulationPipe"),

GENERIC_WRITE,

0,

NULL,

OPEN_EXISTING,

0,

NULL);

if (hPipe != INVALID_HANDLE_VALUE)

{

std::string command;

std::cout << "Enter command (move x,y or click): ";

std::getline(std::cin, command);

if (command == "exit")

break;

DWORD bytesWritten;

WriteFile(hPipe, command.c_str(), command.length(), &bytesWritten, NULL);

CloseHandle(hPipe);

}

else

{

std::cout << "Failed to connect to pipe. Error: " << GetLastError() << std::endl;

Sleep(1000);

}

}

return 0;

}

```

**安装和使用说明**:

  1. **编译服务程序**:

```batch

cl mouse_service.cpp /EHsc /Fe:MouseService.exe

```

  1. **安装服务**:

```batch

sc create MouseSimulationService binPath= "完整路径\MouseService.exe" start= auto

sc start MouseSimulationService

```

  1. **注意事项**:
  • 服务程序需要以 SYSTEM 账户运行

  • 需要适当的权限和桌面访问权限

  • 建议在服务属性中设置"允许服务与桌面交互"

  • 所有操作都会记录到 C:\MouseService.log

  • 服务程序需要管理员权限安装和运行

  1. **主要改进**:
  • 添加了适当的桌面访问权限处理

  • 使用命名管道进行通信

  • 完整的服务生命周期管理

  • 详细的日志记录

  • 错误处理和异常恢复

  1. **限制**:
  • 由于 Windows 安全限制,某些鼠标操作可能在某些情况下不响应

  • 需要正确配置服务权限

  • 在某些 Windows 版本中可能需要额外的安全配置

这个版本的程序已经适配了 Windows 服务环境,但仍然需要注意 Windows 服务的各种限制和安全考虑。建议在实际部署前进行充分测试。

相关推荐
xchenhao8 小时前
基于 Flutter 的开源文本 TTS 朗读器(支持 Windows/macOS/Android)
android·windows·flutter·macos·openai·tts·朗读器
帽儿山的枪手9 小时前
追踪网络流量就这么简单 | 进阶篇 | conntrack
linux·windows·网络协议
兮动人11 小时前
Windows 11 系统关键文件夹详解及安全清理指南
windows·安全
LabVIEW开发15 小时前
LabVIEW调用外部DLL
windows·labview·labview知识·labview功能·labview程序
biubiubiu070615 小时前
FFmpeg Windows安装
windows·ffmpeg
哆啦A梦——17 小时前
dll文件缺失解决方法
windows
漠效18 小时前
Duplicate cleaner pro 的使用技巧
windows·经验分享
DogDaoDao18 小时前
Windows下VScode配置FFmpeg开发环境保姆级教程
windows·vscode·ffmpeg·音视频·gcc
Rudon滨海渔村19 小时前
exe文件图标修改器 - exe图标提取器(ico、png) - 修改360文件夹的图标为windows自带的图标
windows
无名小猴20 小时前
Windows软件卸载
windows