#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);
}
O principal objetivo deste código é iniciar o serviço de impressão do Windows (serviço Spooler) e julgar o status do serviço para o processamento correspondente. O código é dividido nas seguintes etapas principais:
- Contém os arquivos de cabeçalho necessários <Windows.h> e <Winsvc.h> para chamar a API do Windows.
- Chame o OpenSCManager para abrir o gerenciador de controle de serviço para acessar os serviços. Verifique o valor de retorno e lance uma exceção se falhar.
- Chame o OpenService para abrir o serviço a ser acessado, aqui é o serviço Spooler (impressão). Verifique o valor de retorno e lance uma exceção se falhar.
- Chame QueryServiceStatus para obter o status atual do serviço Spooler. Verifique o valor de retorno e lance uma exceção se falhar.
- Determine o status atual do serviço Spooler. Se o status for SERVICE_RUNNING, significa que o serviço foi iniciado, em seguida, emita uma mensagem de prompt e o programa é encerrado.
- Se o serviço não for iniciado, chame StartService para iniciar o serviço Spooler. Verifica se a inicialização foi bem-sucedida e lança uma exceção se falhar.
- Depois de iniciar o serviço, chame continuamente QueryServiceStatus para consultar o status até que o status mude para SERVICE_RUNNING, indicando que a inicialização do serviço foi concluída. Durante este processo, uma mensagem de status de inicialização é emitida.
- Independentemente da direção da lógica do programa, é necessário garantir que os handles de serviço obtidos pelo OpenSCManager e OpenService sejam fechados corretamente para evitar vazamentos de recursos. Portanto, chame CloseServiceHandle para fechar o identificador depois que toda a lógica terminar.
- Use a saída STD (cout) para gerar informações de prompt, o que é conveniente para rastrear o processo de execução e depuração do programa.
- Use a exceção STD do mecanismo de manipulação de exceção (runtime_error) para capturar o erro gerado quando a chamada da API do Windows falha e gerar as informações da exceção. Isso permite que o programa saia normalmente, em vez de travar.
No geral, este é um paradigma de gerenciamento de serviços do Windows relativamente completo e robusto:
- Siga o princípio RAII para gerenciar recursos para garantir a liberação correta de recursos.
- Verifique o valor de retorno das chamadas de API do Windows de maneira abrangente e detalhada e execute o tratamento de erros e os prompts necessários.
- Use exceções STD para manipulação de exceção para evitar travamentos do programa.
- Gere informações detalhadas de depuração, o que é conveniente para rastrear o processo de execução do programa.
- Escolha iniciar o serviço ou exibir um prompt de acordo com o estado atual do serviço, em vez de iniciá-lo às cegas, para evitar operações desnecessárias.