Windows中注册并启动服务
一、Windows服务相关函数
(1).OpenSCManager函数
OpenSCManager
函数用于打开一个服务控制管理器数据库(Service Control Manager Database)。服务控制管理器是 Windows 操作系统中的一个组件,用于管理系统上运行的服务。通过服务控制管理器,您可以创建、删除、启动、停止和查询服务,还可以获取有关服务的信息。
以下是 OpenSCManager
函数的基本介绍和使用方法:
1 2 3 4 5 | SC_HANDLE OpenSCManager( LPCWSTR lpMachineName, LPCWSTR lpDatabaseName, DWORD dwDesiredAccess ); |
参数说明:
lpMachineName
:要连接的远程计算机的名称。如果要连接本地计算机,可以设置为NULL
。lpDatabaseName
:要打开的数据库名称。通常为"Services"
,用于指定对服务控制管理器数据库(Service Control Manager Database)的完全访问权限。服务控制管理器允许您管理系统上运行的服务,包括创建、删除、启动、停止和查询服务,以及获取有关服务的信息。dwDesiredAccess
:所需的访问权限。例如,SC_MANAGER_ALL_ACCESS
表示连接到服务控制管理器。
返回值:
- 如果成功,返回一个类型为
SC_HANDLE
的服务控制管理器句柄。 - 如果失败,返回
NULL
。您可以使用GetLastError
函数来获取更多错误信息。
使用示例:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | #include <Windows.h> #include <iostream> int main() { SC_HANDLE scm = OpenSCManager(NULL, NULL,SC_MANAGER_ALL_ACCESS); if (scm == NULL) { std::cerr << "Failed to open service manager." << std::endl; return 1; } // 在此处进行操作,例如创建、启动、停止服务等 CloseServiceHandle(scm); return 0; } |
在上述示例中,使用 OpenSCManager
打开了服务控制管理器数据库。然后可以在获取到的句柄 scm
上执行各种操作,如创建、启动、停止服务等。完成操作后,不要忘记调用 CloseServiceHandle
关闭服务控制管理器句柄。
(2).CreateService函数
CreateService
函数用于在服务控制管理器数据库中创建一个新的服务。服务控制管理器是 Windows 操作系统的一个组件,用于管理系统上运行的服务。通过 CreateService
函数,您可以指定服务的各种属性,如名称、显示名称、类型、启动类型、二进制路径等。
以下是 CreateService
函数的基本介绍和使用方法:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | SC_HANDLE CreateService( SC_HANDLE hSCManager, LPCWSTR lpServiceName, LPCWSTR lpDisplayName, DWORD dwDesiredAccess, DWORD dwServiceType, DWORD dwStartType, DWORD dwErrorControl, LPCWSTR lpBinaryPathName, LPCWSTR lpLoadOrderGroup, LPDWORD lpdwTagId, LPCWSTR lpDependencies, LPCWSTR lpServiceStartName, LPCWSTR lpPassword ); |
参数说明:
hSCManager
:打开的服务控制管理器句柄,通常是由OpenSCManager
函数获得的。lpServiceName
:服务的名称,用于标识服务。这个名称必须是唯一的。lpDisplayName
:服务的显示名称,用户可读的名称。dwDesiredAccess
:对服务的访问权限。通常使用SERVICE_ALL_ACCESS
或其他适当的访问权限常量。dwServiceType
:服务类型,如SERVICE_WIN32_OWN_PROCESS
。dwStartType
:启动类型,如SERVICE_AUTO_START
。dwErrorControl
:错误控制,如SERVICE_ERROR_NORMAL
。lpBinaryPathName
:可执行文件的路径,包括参数。这个文件将作为服务的主体运行。- 其他参数用于指定组、标签、依赖项、服务启动用户名等。对于大多数情况,您可以设置为
NULL
。
返回值:
- 如果成功,返回一个类型为
SC_HANDLE
的服务句柄。 - 如果失败,返回
NULL
。您可以使用GetLastError
函数来获取更多错误信息。
使用示例:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 | #include <Windows.h> #include <iostream> int main() { SC_HANDLE scm = OpenSCManager(NULL, NULL, SC_MANAGER_CREATE_SERVICE); if (scm == NULL) { std::cerr << "Failed to open service manager." << std::endl; return 1; } const wchar_t *serviceName = L "MyServiceName" ; const wchar_t *serviceDisplayName = L "My Service Display Name" ; const wchar_t *binaryPath = L "C:\\Path\\To\\Your\\Service.exe" ; // 替换为实际的可执行文件路径 SC_HANDLE service = CreateService( scm, serviceName, serviceDisplayName, SERVICE_ALL_ACCESS, SERVICE_WIN32_OWN_PROCESS, SERVICE_AUTO_START, SERVICE_ERROR_NORMAL, binaryPath, NULL, NULL, NULL, NULL, NULL ); if (service == NULL) { std::cerr << "Failed to create service." << std::endl; CloseServiceHandle(scm); return 1; } std::cout << "Service created successfully." << std::endl; CloseServiceHandle(service); CloseServiceHandle(scm); return 0; } |
在上述示例中,使用 CreateService
函数创建了一个新的服务。请注意,要创建服务通常需要管理员权限。同时,确保在实际应用中提供正确的参数,如服务名称、显示名称、二进制路径等。完成操作后,不要忘记调用 CloseServiceHandle
关闭服务句柄和服务控制管理器句柄。
(3).OpenService函数
OpenService
函数用于打开一个现有的服务,以便您可以执行对该服务的操作,如启动、停止、查询状态等。您需要提供服务所在的服务控制管理器数据库的句柄以及服务的名称。
以下是 OpenService
函数的基本介绍和使用方法:
1 2 3 4 5 | SC_HANDLE OpenService( SC_HANDLE hSCManager, LPCWSTR lpServiceName, DWORD dwDesiredAccess ); |
参数说明:
hSCManager
:已经打开的服务控制管理器句柄,通常是通过OpenSCManager
函数获取的。lpServiceName
:服务的名称,您要打开的现有服务的标识符。dwDesiredAccess
:您希望获取的服务访问权限。通常使用SERVICE_ALL_ACCESS
或其他适当的访问权限常量。
返回值:
- 如果成功,返回一个类型为
SC_HANDLE
的服务句柄。 - 如果失败,返回
NULL
。您可以使用GetLastError
函数来获取更多错误信息。
使用示例:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 | #include <Windows.h> #include <iostream> int main() { SC_HANDLE scm = OpenSCManager(NULL, NULL, SC_MANAGER_CONNECT); if (scm == NULL) { std::cerr << "Failed to open service manager." << std::endl; return 1; } const wchar_t *serviceName = L "MyServiceName" ; SC_HANDLE service = OpenService(scm, serviceName, SERVICE_ALL_ACCESS); if (service == NULL) { std::cerr << "Failed to open service." << std::endl; CloseServiceHandle(scm); return 1; } // 在此处进行操作,如查询服务状态、启动、停止等 CloseServiceHandle(service); CloseServiceHandle(scm); return 0; } |
(4).QueryServiceStatus函数
QueryServiceStatus
函数用于查询指定服务的当前状态。您可以使用这个函数来获取有关服务的信息,如服务是否正在运行、服务的当前状态等。
以下是 QueryServiceStatus
函数的基本介绍和使用方法:
1 2 3 4 | BOOL QueryServiceStatus( SC_HANDLE hService, LPSERVICE_STATUS lpServiceStatus ); |
参数说明:
hService
:要查询状态的服务句柄,通常是通过OpenService
函数获得的。lpServiceStatus
:一个指向SERVICE_STATUS
结构的指针,用于接收查询到的服务状态信息。
返回值:
- 如果成功,返回非零值 (
TRUE
)。 - 如果失败,返回零 (
FALSE
)。您可以使用GetLastError
函数来获取更多错误信息。
SERVICE_STATUS
结构包含了有关服务状态的信息,包括当前状态、进程 ID、计数器等。以下是结构的一些字段:
1 2 3 4 5 6 7 8 9 | typedef struct _SERVICE_STATUS { DWORD dwServiceType; DWORD dwCurrentState; DWORD dwControlsAccepted; DWORD dwWin32ExitCode; DWORD dwServiceSpecificExitCode; DWORD dwCheckPoint; DWORD dwWaitHint; } SERVICE_STATUS, *LPSERVICE_STATUS; |
dwServiceType
:服务类型,如SERVICE_WIN32_OWN_PROCESS
。dwCurrentState
:当前服务状态,如SERVICE_RUNNING
。dwControlsAccepted
:接受的控制代码,如SERVICE_ACCEPT_STOP
。dwWin32ExitCode
:Win32 退出代码。dwServiceSpecificExitCode
:服务特定的退出代码。dwCheckPoint
:用于报告服务状态检查点。dwWaitHint
:等待时间估计。
使用示例:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 | #include <Windows.h> #include <iostream> int main() { SC_HANDLE scm = OpenSCManager(NULL, NULL, SC_MANAGER_CONNECT); if (scm == NULL) { std::cerr << "Failed to open service manager." << std::endl; return 1; } const wchar_t *serviceName = L "MyServiceName" ; SC_HANDLE service = OpenService(scm, serviceName, SERVICE_QUERY_STATUS); if (service == NULL) { std::cerr << "Failed to open service." << std::endl; CloseServiceHandle(scm); return 1; } SERVICE_STATUS serviceStatus; if (QueryServiceStatus(service, &serviceStatus)) { if (serviceStatus.dwCurrentState == SERVICE_RUNNING) { std::cout << "Service is running." << std::endl; } else if (serviceStatus.dwCurrentState == SERVICE_STOPPED) { std::cout << "Service is stopped." << std::endl; } else { std::cout << "Service is in another state." << std::endl; } } else { std::cerr << "Failed to query service status." << std::endl; } CloseServiceHandle(service); CloseServiceHandle(scm); return 0; } |
5.ControlService函数
ControlService
函数用于向一个已经打开的服务发送控制代码,从而控制服务的行为,例如启动、停止、暂停、恢复等。
以下是 ControlService
函数的基本介绍和使用方法:
1 2 3 4 5 | BOOL ControlService( SC_HANDLE hService, DWORD dwControl, LPSERVICE_STATUS lpServiceStatus ); |
参数说明:
hService
:已经打开的服务句柄,通常是通过OpenService
函数获取的。dwControl
:控制代码,指定要发送的控制操作,如SERVICE_CONTROL_STOP
用于停止服务。lpServiceStatus
:一个指向SERVICE_STATUS
结构的指针,用于接收服务状态信息。
返回值:
- 如果成功,返回非零值 (
TRUE
)。 - 如果失败,返回零 (
FALSE
)。您可以使用GetLastError
函数来获取更多错误信息。
dwControl
参数可以是以下值之一,表示不同的控制操作:
SERVICE_CONTROL_CONTINUE
:继续暂停的服务。SERVICE_CONTROL_INTERROGATE
:查询服务状态。SERVICE_CONTROL_PAUSE
:暂停服务。SERVICE_CONTROL_STOP
:停止服务。- ... 等其他控制代码。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 | #include <Windows.h> #include <iostream> int main() { SC_HANDLE scm = OpenSCManager(NULL, NULL, SC_MANAGER_CONNECT); if (scm == NULL) { std::cerr << "Failed to open service manager." << std::endl; return 1; } const wchar_t *serviceName = L "MyServiceName" ; SC_HANDLE service = OpenService(scm, serviceName, SERVICE_STOP | SERVICE_QUERY_STATUS); if (service == NULL) { std::cerr << "Failed to open service." << std::endl; CloseServiceHandle(scm); return 1; } SERVICE_STATUS serviceStatus; if (ControlService(service, SERVICE_CONTROL_STOP, &serviceStatus)) { std::cout << "Service control request sent successfully." << std::endl; } else { std::cerr << "Failed to send service control request." << std::endl; } CloseServiceHandle(service); CloseServiceHandle(scm); return 0; } |
6.StartService函数
StartService
函数用于启动一个已经打开的服务。您可以使用这个函数来启动服务,将其从停止状态切换为运行状态。
以下是 StartService
函数的基本介绍和使用方法:
1 2 3 4 5 | BOOL StartService( SC_HANDLE hService, DWORD dwNumServiceArgs, LPCTSTR *lpServiceArgVectors ); |
参数说明:
hService
:已经打开的服务句柄,通常是通过OpenService
函数获取的。dwNumServiceArgs
:提供给服务的参数个数。lpServiceArgVectors
:指向参数数组的指针,这个参数可以为NULL
。
返回值:
- 如果成功,返回非零值 (
TRUE
)。 - 如果失败,返回零 (
FALSE
)。您可以使用GetLastError
函数来获取更多错误信息。
使用示例:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 | #include <Windows.h> #include <iostream> int main() { SC_HANDLE scm = OpenSCManager(NULL, NULL, SC_MANAGER_CONNECT); if (scm == NULL) { std::cerr << "Failed to open service manager." << std::endl; return 1; } const wchar_t *serviceName = L "MyServiceName" ; SC_HANDLE service = OpenService(scm, serviceName, SERVICE_START); if (service == NULL) { std::cerr << "Failed to open service." << std::endl; CloseServiceHandle(scm); return 1; } if (StartService(service, 0, NULL)) { std::cout << "Service started successfully." << std::endl; } else { std::cerr << "Failed to start service." << std::endl; } CloseServiceHandle(service); CloseServiceHandle(scm); return 0; } |
二、注册并启动服务的完整示例
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 | #include <Windows.h> #include <iostream> BOOL start_monitor_service( const char * service_name, const char * service_display_name, const char * service_path) { //打开服务管理器 SC_HANDLE scm = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS); if (scm == NULL) { std::cout << "Failed to open service manager:" << GetLastError() << std::endl; return FALSE; } wchar_t w_service_name[256] = { 0 }; mbstowcs (w_service_name, service_name, strlen (service_name) + 1); wchar_t w_service_display_name[256] = { 0 }; mbstowcs (w_service_display_name, service_display_name, strlen (service_display_name) + 1); wchar_t w_service_path[256] = { 0 }; mbstowcs (w_service_path, service_path, strlen (service_path) + 1); //注册服务 SC_HANDLE create_service = CreateService( scm, w_service_name, w_service_display_name, SERVICE_ALL_ACCESS, SERVICE_WIN32_OWN_PROCESS, SERVICE_AUTO_START, SERVICE_ERROR_NORMAL, w_service_path, NULL, NULL, NULL, NULL, NULL ); if (create_service == NULL) { std::cout << "Failed to create service:" << GetLastError() << std::endl; CloseServiceHandle(scm); return FALSE; } //打开要启动的服务 SC_HANDLE open_service = OpenService(scm, w_service_name, SERVICE_START); if (open_service == NULL) { std::cout << "Failed to open service" << GetLastError() << std::endl; CloseServiceHandle(create_service); CloseServiceHandle(scm); return FALSE; } //启动服务 if (!StartService(open_service, 0, NULL)) { std::cout << "Failed to start service:" << GetLastError() << std::endl; CloseServiceHandle(open_service); CloseServiceHandle(create_service); CloseServiceHandle(scm); return FALSE; } std::cout << "Service registered successfully" << std::endl; //查询服务状态 SERVICE_STATUS service_status; if (!QueryServiceStatus(open_service, &service_status)) { std::cout << "Failed to query service status:" << GetLastError() << std::endl; CloseServiceHandle(open_service); CloseServiceHandle(create_service); CloseServiceHandle(scm); return false ; } //判断服务的运行状态 if (service_status.dwCurrentState == SERVICE_RUNNING) { //停止服务 if (ControlService(open_service, SERVICE_CONTROL_STOP, &service_status)) { std::cout << "Service stoping..." << std::endl; /* SERVICE_STOP_PENDING:这个常量表示服务正在停止过程中,但尚未完全停止。当您发送停止命令给服务时, 服务可能需要一些时间来完成清理和停止操作,这时服务状态会被设置为 SERVICE_STOP_PENDING。 */ //等待服务停止 while (service_status.dwCurrentState == SERVICE_STOP_PENDING) { Sleep(1000); if (!QueryServiceStatus(open_service, &service_status)) { std::cout << "Failed to query service status." << std::endl; break ; } } /* SERVICE_STOPPED:这个常量表示服务已经完全停止。当服务停止操作完成后,服务状态会被设置为 SERVICE_STOPPED。 */ if (service_status.dwCurrentState == SERVICE_STOPPED) { std::cout << "Service stopped successfully." << std::endl; } else { std::cerr << "Failed to stop service." << std::endl; } } } CloseServiceHandle(open_service); CloseServiceHandle(create_service); CloseServiceHandle(scm); return true ; } |
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· DeepSeek 开源周回顾「GitHub 热点速览」
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· AI与.NET技术实操系列(二):开始使用ML.NET
· 单线程的Redis速度为什么快?