[Update 04/07/2007] Se você pretende criar uma aplicação para rodar como serviço e sabe que ela precisará de uma interface gráfica para entrada de dados, a melhor solução é criar o serviço em um projeto e a GUI em outro (dois executáveis).
Desta forma, você deverá estabelecer algum meio de comunicação entre a GUI e o serviço. Para isto, poderá usar sockets, objetos distribuídos (acho que não compensa), named pipes ou qualquer outro recurso de compartilhamento de memória entre processos.
Estas foram as conclusões que eu e outro colega de trabalho chegamos após diversos testes com um serviço que precisava de uma interface para administrá-lo. [Fim do update]
Os serviços do windows são uma boa solução quando você precisa executar alguma tarefa antes do login de qualquer usuário no sistema.
Na empresa onde trabalho atualmente, utilizamos esta tecnologia em um servidor que gerencia o acesso dos usuários ao sistema.
Neste post apresento como criar um serviço a partir de uma aplicação pronta. Além disso, também vou descrever alguns detalhes que só a experiência em trabalhar com esta tecnologia pode trazer à tona.
Os exemplos foram criados com base no Delphi 6 e utilizando o Windows XP.
- Criando o serviço
Antes de tudo, é claro, você deve ter uma aplicação normal para transformá-la em um serviço. Com ela aberta no Delphi, vá até o menu File / New / Other e escolha o item Service. Veja:

Com o serviço criado (eu chamei de srvServidor) você deve fazer as seguintes alterações:
Projeto (dpr): o uses Forms deve ser removido e o SvcMgr adicionado. Além disso, o único objeto que deve ser criado na inicialização é o serviço. Veja:

Implementar o método Execute: o serviço possui um método chamado Execute. É nele que você deverá criar a tela principal da sua aplicação. Veja:

Ignore por enquanto a inicialização do COM (método CoInitialize) . Ela será explicada mais adiante.
Instalar o serviço: a instalação de um serviço no windows é feita executando a aplicação com o parâmetro /INSTALL. A desinstalação é feita com o /UNINSTALL. Veja um exemplo:

- Adaptando o executável para rodar como um serviço
Existem diversas alterações que você deve fazer para rodar sua aplicação como um serviço. Abaixo segue uma lista das mais comuns.
Objeto TService
A primeira alteração deve ser feita no objeto TService criado anteriormente. Você precisa definir as seguintes propriedades:
- DisplayName: nome que aparecerá na lista de serviços;
- Interactive: define se o serviço poderá se comunicar com o Desktop ou não. Para mostrar um form ou até mesmo uma simples mensagem (ShowMessage, por exemplo), esta propriedade deve estar definida como true.
Inicialização do COM
Se a sua aplicação utiliza algum objeto COM, você deverá inicializar o suporte ao COM com o método CoInitialize. Isto pode ser visto no método Execute apresentado acima.
Sem esta alteração, provavelmente você receberá uma mensagem do tipo “CoInitialize has not been called” ao rodar o serviço.
Método GetCurrentDir
O método GetCurrentDir quando utilizado em um serviço retorna sempre c:\windows\System32. Eu não achei em lugar algum documentação que explicasse este comportamento.
Para contornar este problema, utilizei o ParamStr(0) juntamente com ExtractFilePath.
OnMouseLeave
Se você utiliza este evento em Labels (talvez em outros componentes também), terá que esquecê-lo. Em todos os testes que fiz o OnMouseLeave não foi executado. Logo, deixei de usá-lo.
FormStyle
O form principal de uma aplicação normalmente é do tipo fsMDIForm. Em um serviço você deverá alterar esta propriedade para fsNormal.
Nos testes que fiz, ao utilizar o tipo fsMDIForm não foi possível modificar a propriedade Visible de alguns frames.
É isso ae.
Até +.