#include <Windows.h>
#include <Winsvc.h>
#include <iostream>
using namespace std;
int main()
{
// 打开SC管理器
SC_HANDLE schSCManager = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS);
if (schSCManager == NULL)
{
throw runtime_error("OpenSCManager failed!");
}
// 打开spooler服务
SC_HANDLE schService = OpenService(schSCManager, "Spooler", SERVICE_ALL_ACCESS);
if (schService == NULL)
{
throw runtime_error("OpenService failed!");
}
// 判断spooler服务状态
SERVICE_STATUS ssStatus;
if (!QueryServiceStatus(schService, &ssStatus))
{
throw runtime_error("QueryServiceStatus failed!");
}
// 如果spooler服务已启动,提示服务正常
if (ssStatus.dwCurrentState == SERVICE_RUNNING)
{
cout << "Spooler service is running." << endl;
}
else // 否则启动spooler服务
{
// 启动spooler服务
BOOL bRet = StartService(schService, 0, NULL);
if (!bRet)
{
throw runtime_error("StartService failed!");
}
cout << "Starting Spooler service..." << endl;
// 等待服务启动完成
while (QueryServiceStatus(schService, &ssStatus))
{
if (ssStatus.dwCurrentState == SERVICE_START_PENDING)
{
cout << "Spooler service is starting..." << endl;
}
else if (ssStatus.dwCurrentState == SERVICE_RUNNING)
{
cout << "Spooler service is running!" << endl;
break;
}
}
}
// 关闭句柄
CloseServiceHandle(schService);
CloseServiceHandle(schSCManager);
}
这段代码的主要目的是启动Windows的打印服务(Spooler服务),并判断服务状态进行相应的处理。代码分为以下主要步骤:
- 包含必要的头文件<Windows.h>和<Winsvc.h>,用于调用Windows API。
- 调用OpenSCManager打开服务控制管理器,用于访问服务。检查返回值,如果失败则抛出异常。
- 调用OpenService打开准备访问的服务,此处是Spooler(打印)服务。检查返回值,如果失败则抛出异常。
- 调用QueryServiceStatus获取Spooler服务的当前状态。检查返回值,如果失败则抛出异常。
- 判断Spooler服务的当前状态。如果状态为SERVICE_RUNNING,表示服务已启动,则输出提示信息,程序退出。
- 如果服务未启动,则调用StartService启动Spooler服务。检查启动是否成功,如果失败则抛出异常。
- 启动服务后不断调用QueryServiceStatus查询状态,直到状态变为SERVICE_RUNNING,表示服务启动完成。在此过程中输出启动状态提示。
- 无论程序逻辑走向如何,都需要确保OpenSCManager、OpenService获取的服务句柄正确关闭,避免资源泄露。因此在所有逻辑结束后调用CloseServiceHandle关闭句柄。
- 使用STD输出(cout)输出提示信息,方便跟踪程序执行过程和调试。
- 使用异常处理机制STD异常(runtime_error)捕获Windows API调用失败时产生的错误,并输出异常信息。这可以使程序优雅退出,而不是崩溃。
总体来说,这是一个比较完整和健壮的Windows服务管理范例:
- 遵循RAII原则管理资源,保证资源正确释放。
- 全面、详细地检查Windows API调用的返回值,进行必要的错误处理与提示。
- 使用STD异常进行异常处理,避免程序崩溃。
- 输出详细的调试信息,便于跟踪程序执行过程。
- 根据服务当前状态选择启动服务或输出提示,而非一味启动,避免无谓操作。