Compartilhar via


LPSERVICE_MAIN_FUNCTIONW função de retorno de chamada (winsvc.h)

O ponto de entrada de um serviço.

O tipo LPSERVICE_MAIN_FUNCTION define um ponteiro para essa função de retorno de chamada. ServiceMain é um espaço reservado para um nome de função definido pelo aplicativo.

Sintaxe

LPSERVICE_MAIN_FUNCTIONW LpserviceMainFunctionw;

void LpserviceMainFunctionw(
  [in] DWORD dwNumServicesArgs,
  [in] LPWSTR *lpServiceArgVectors
)
{...}

Parâmetros

[in] dwNumServicesArgs

O número de argumentos na matriz lpServiceArgVectors.

[in] lpServiceArgVectors

As cadeias de caracteres de argumento terminadas em nulo passadas para o serviço pela chamada para a função StartService que iniciou o serviço. Se não houver argumentos, esse parâmetro poderá ser NULL. Caso contrário, o primeiro argumento (lpServiceArgVectors[0]) é o nome do serviço, seguido por quaisquer argumentos adicionais (lpServiceArgVectors[1] por meio de lpServiceArgVectors[dwNumServicesArgs-1]).

Se o usuário iniciar um serviço manual usando o snap-in serviços do Painel de Controle, as cadeias de caracteres para o parâmetro lpServiceArgVectors vêm da caixa de diálogo propriedades do serviço (do snap-in Serviços, clique com o botão direito do mouse na entrada do serviço, clique em Propriedadese insira os parâmetros em parâmetros iniciar.)

Valor de retorno

Nenhum

Observações

Um programa de serviço pode iniciar um ou mais serviços. Um processo de serviço tem uma estrutura SERVICE_TABLE_ENTRY para cada serviço que ele pode iniciar. A estrutura especifica o nome do serviço e um ponteiro para a função ServiceMain para esse serviço.

Quando o gerenciador de controle de serviço recebe uma solicitação para iniciar um serviço, ele inicia o processo de serviço (se ele ainda não estiver em execução). O thread principal do processo de serviço chama a função StartServiceCtrlDispatcher com um ponteiro para uma matriz de estruturas de SERVICE_TABLE_ENTRY. Em seguida, o gerenciador de controle de serviço envia uma solicitação inicial ao dispatcher de controle de serviço para esse processo de serviço. O dispatcher de controle de serviço cria um novo thread para executar a função ServiceMain do serviço que está sendo iniciado.

A função ServiceMain deve chamar imediatamente a função RegisterServiceCtrlHandlerEx para especificar uma função HandlerEx para lidar com solicitações de controle. Em seguida, ele deve chamar a função SetServiceStatus para enviar informações de status ao gerenciador de controle de serviço. Após essas chamadas, a função deve concluir a inicialização do serviço. Não tente iniciar outro serviço na função ServiceMain.

O SCM (Service Control Manager) aguarda até que o serviço reporte um status de SERVICE_RUNNING. É recomendável que o serviço reporte esse status o mais rápido possível, pois outros componentes no sistema que exigem interação com o SCM serão bloqueados durante esse tempo. Algumas funções podem exigir interação com o SCM direta ou indiretamente.

O SCM bloqueia o banco de dados de controle de serviço durante a inicialização, portanto, se um serviço tentar chamar StartService durante a inicialização, a chamada será bloqueada. Quando o serviço relata ao SCM que foi iniciado com êxito, ele pode chamar StartService. Se o serviço exigir que outro serviço esteja em execução, o serviço deverá definir as dependências necessárias.

Além disso, você não deve chamar nenhuma função do sistema durante a inicialização do serviço. O código de serviço deve chamar as funções do sistema somente depois de relatar um status de SERVICE_RUNNING.

A função ServiceMain deve criar um evento global, chamar a função RegisterWaitForSingleObject neste evento e sair. Isso encerrará o thread que está executando a função ServiceMain, mas não encerrará o serviço. Quando o serviço está parando, o manipulador de controle de serviço deve chamar SetServiceStatus com SERVICE_STOP_PENDING e sinalizar esse evento. Um thread do pool de threads executará a função de retorno de chamada de espera; essa função deve executar tarefas de limpeza, incluindo fechar o evento global e chamar SetServiceStatus com SERVICE_STOPPED. Depois que o serviço for interrompido, você não deverá executar nenhum código de serviço adicional porque poderá introduzir uma condição de corrida se o serviço receber um controle inicial e do ServiceMain for chamado novamente. Observe que esse problema é mais provável quando vários serviços compartilham um processo.

Exemplos

Para obter um exemplo, consulte Gravando uma função ServiceMain.

Nota

O cabeçalho winsvc.h define LPSERVICE_MAIN_FUNCTION como um alias que seleciona automaticamente a versão ANSI ou Unicode dessa função com base na definição da constante do pré-processador UNICODE. A combinação do uso do alias neutro de codificação com código que não é neutro em codificação pode levar a incompatibilidades que resultam em erros de compilação ou de runtime. Para obter mais informações, consulte Conventions for Function Prototypes.

Requisitos

Requisito Valor
de cliente com suporte mínimo Windows XP [somente aplicativos da área de trabalho]
servidor com suporte mínimo Windows Server 2003 [somente aplicativos da área de trabalho]
da Plataforma de Destino Windows
cabeçalho winsvc.h (incluir Windows.h)

Consulte também

HandlerEx

RegisterServiceCtrlHandlerEx

RegisterWaitForSingleObject

SERVICE_TABLE_ENTRY

Funções de serviço

de função ServiceMain do

SetServiceStatus

StartServiceCtrlDispatcher