Existe uma maneira mais fácil de percorrer o código do que iniciar o serviço por meio do Windows Service Control Manager e depois anexar o depurador ao encadeamento? É meio complicado e estou me perguntando se existe uma abordagem mais direta.
c#
debugging
windows-services
Matthias
fonte
fonte
Respostas:
Se eu quiser depurar rapidamente o serviço, simplesmente entrei
Debugger.Break()
lá. Quando essa linha é alcançada, ela volta ao VS. Não se esqueça de remover essa linha quando terminar.ATUALIZAÇÃO: Como alternativa aos
#if DEBUG
pragmas, você também pode usar oConditional("DEBUG_SERVICE")
atributo.No seu caso
OnStart
, basta chamar este método:Lá, o código será ativado apenas durante as compilações de depuração. Enquanto você estiver trabalhando nisso, pode ser útil criar uma Configuração de Compilação separada para depuração do serviço.
fonte
Também acho que ter uma "versão" separada para execução normal e como serviço é o caminho a percorrer, mas é realmente necessário dedicar uma opção de linha de comando separada para esse fim?
Você não poderia simplesmente fazer:
Isso teria o "benefício", que você pode simplesmente iniciar seu aplicativo via clique duplo (OK, se você realmente precisar disso) e clicar F5no Visual Studio (sem a necessidade de modificar as configurações do projeto para incluir isso)
/console
opção).Tecnicamente,
Environment.UserInteractive
verifica se oWSF_VISIBLE
Sinalizador está definido para a estação atual da janela, mas existe algum outro motivo para retornarfalse
, além de ser executado como um serviço (não interativo)?fonte
System.Diagnostics.Debugger.IsAttached
vez deEnvironment.UserInteractive
.Quando configurei um novo projeto de serviço, há algumas semanas, encontrei este post. Embora haja muitas ótimas sugestões, ainda não encontrei a solução que queria: a possibilidade de chamar as classes de serviço
OnStart
eOnStop
métodos sem nenhuma modificação nas classes de serviço.A solução que eu criei usa o
Environment.Interactive
modo de execução select, conforme sugerido por outras respostas a este post.O
RunInteractive
auxiliar usa reflexão para chamar os métodos protectedOnStart
eOnStop
:Este é todo o código necessário, mas também escrevi orientações com explicações.
fonte
walk through
) é garantir que você vá para as propriedades do projeto e altere o tipo de saída paraConsole Application
antes de tentar compilar e executar. Encontre-o emProject Properties -> Application -> Output type -> Console Application
. Além disso, para que isso funcionasse corretamente, acabei tendo que executar o aplicativo usando ostart
comando Ex:C:\"my app name.exe" -service
não funcionaria para mim. Em vez disso eu useiC:\start /wait "" "my app name.exe" -service
Às vezes, é importante analisar o que está acontecendo durante a inicialização do serviço. Anexar ao processo não ajuda aqui, porque você não é rápido o suficiente para anexar o depurador enquanto o serviço está sendo iniciado.
A resposta curta é: estou usando as 4 linhas de código a seguir para fazer isso:
Eles são inseridos no
OnStart
método do serviço da seguinte maneira:Para aqueles que não fizeram isso antes, incluímos dicas detalhadas abaixo , porque você pode facilmente ficar preso. As dicas a seguir se referem ao Windows 7x64 e ao Visual Studio 2010 Team Edition , mas também devem ser válidas para outros ambientes.
Importante: Implemente o serviço no modo "manual" (usando o
InstallUtil
utilitário no prompt de comandos do VS ou execute um projeto do instalador de serviço que você preparou). Abra o Visual Studio antes de iniciar o serviço e carregue a solução que contém o código-fonte do serviço - configure pontos de interrupção adicionais conforme necessário no Visual Studio - e inicie o serviço via Painel de Controle Serviço.Devido ao
Debugger.Launch
código, isso causará uma caixa de diálogo "Ocorreu uma exceção não tratada do Microsoft .NET Framework no Servicename.exe ". aparecer. Clique como mostrado na captura de tela: Yes, debug Servicename.exePosteriormente, principalmente no UAC do Windows 7, você poderá solicitar credenciais de administrador. Digite-os e continue com Yes:
Depois disso, a janela conhecida do depurador just-in-time do Visual Studio é exibida. Ele pergunta se você deseja depurar usando o depurador excluído. Antes de clicar Yes, selecione que você não deseja abrir uma nova instância (segunda opção) - uma nova instância não seria útil aqui, porque o código-fonte não seria exibido. Então você seleciona a instância do Visual Studio que você abriu anteriormente:
Depois de clicar Yes, depois de um tempo, o Visual Studio mostrará a seta amarela na linha em
Debugger.Launch
que está a instrução e você poderá depurar seu código (métodoMyInitOnStart
, que contém sua inicialização).Pressionar F5continua a execução imediatamente, até o próximo ponto de interrupção que você preparou.
Dica: Para manter o serviço em execução, selecione Depurar -> Desanexar tudo . Isso permite que você execute um cliente se comunicando com o serviço depois que ele foi iniciado corretamente e você terminou de depurar o código de inicialização. Se você pressionar Shift+F5 (parar a depuração), isso encerrará o serviço. Em vez de fazer isso, você deve usar o Painel de Controle do Serviço para interrompê-lo.
Note que
Se você criar uma versão, o código de depuração será automaticamente removido e o serviço será executado normalmente.
Estou usando
Debugger.Launch()
, que inicia e anexa um depurador . Também testeiDebugger.Break()
, o que não funcionou , porque ainda não existe um depurador conectado na inicialização do serviço (causando o "Erro 1067: O processo foi encerrado inesperadamente" ).RequestAdditionalTime
define um longo tempo de espera para o arranque do serviço (que é não atrasar o código em si, mas vai continuar imediatamente com aDebugger.Launch
declaração). Caso contrário, o tempo limite padrão para iniciar o serviço é muito curto e o serviço falhará se você não ligar combase.Onstart(args)
rapidez suficiente no depurador. Praticamente, um tempo limite de 10 minutos evita que você veja a mensagem " o serviço não respondeu ..." imediatamente após o início do depurador.Depois de se acostumar, esse método é muito fácil, pois exige apenas a adição de 4 linhas a um código de serviço existente, permitindo que você obtenha rapidamente controle e depuração.
fonte
base.RequestAdditionalTime(600000)
impedirá que o controle de serviço encerre o serviço por 10 minutos, se ele não ligarbase.OnStart(args)
dentro desse prazo). Além disso, lembro que o UAC também será abortado se você não inserir as credenciais de administrador depois de um tempo (não sei exatamente quantos segundos, mas acho que você deve inseri-lo em um minuto, caso contrário, o UAC anula) , que encerrará a sessão de depuração.O que eu costumo fazer é encapsular a lógica do serviço em uma classe separada e iniciá-la a partir de uma classe 'runner'. Essa classe de corredor pode ser o serviço real ou apenas um aplicativo de console. Portanto, sua solução possui (pelo menos) três projetos:
fonte
Este vídeo do YouTube de Fabio Scopel explica como depurar um serviço do Windows bastante bem ... o método real de fazer isso começa às 4:45 no vídeo ...
Aqui está o código explicado no vídeo ... no seu arquivo Program.cs, adicione o material para a seção Debug ...
No seu arquivo Service1.cs, adicione o método OnDebug () ...
Basicamente, você precisa criar um
public void OnDebug()
que chame oOnStart(string[] args)
como está protegido e não pode ser acessado fora. Ovoid Main()
programa é adicionado com o#if
pré-processador com#DEBUG
.O Visual Studio define
DEBUG
se o projeto é compilado no modo de Depuração. Isso permitirá que a seção de depuração (abaixo) seja executada quando a condição for verdadeiraE ele será executado como um aplicativo de console. Quando tudo der certo, você poderá alterar o modo
Release
e aelse
seção regular ativará a lógica.fonte
ATUALIZAR
Essa abordagem é de longe a mais fácil:
http://www.codeproject.com/KB/dotnet/DebugWinServices.aspx
Deixo minha resposta original abaixo para a posteridade.
Meus serviços tendem a ter uma classe que encapsula um Timer, pois quero que o serviço verifique regularmente se existe algum trabalho para ele fazer.
Iniciamos a classe e chamamos StartEventLoop () durante a inicialização do serviço. (Essa classe também pode ser usada com facilidade em um aplicativo de console.)
O bom efeito colateral desse design é que os argumentos com os quais você configurou o Timer podem ter um atraso antes que o serviço realmente comece a funcionar, para que você tenha tempo para anexar um depurador manualmente.
Também costumava fazer o seguinte (já mencionado nas respostas anteriores, mas com os sinalizadores do compilador condicional [#if] para ajudar a evitar o disparo em uma versão).
Parei de fazê-lo dessa maneira, porque às vezes esquecíamos de criar o Release e interrompíamos o depurador em um aplicativo em execução em uma demonstração do cliente (embaraçoso!).
fonte
// do something
leva mais de 30 minutos para ser concluído?fonte
OnStart
éprotected
e você não pode modificar o nível de acesso :(Você também pode iniciar o serviço através do prompt de comando (sc.exe).
Pessoalmente, eu executaria o código como um programa independente na fase de depuração e, quando a maioria dos erros for resolvida, mude para execução como serviço.
fonte
O que eu costumava fazer era ter uma opção de linha de comando que iniciasse o programa como um serviço ou como um aplicativo regular. Então, no meu IDE, eu definiria a opção para que eu pudesse percorrer meu código.
Em alguns idiomas, é possível detectar se ele está sendo executado em um IDE e executar essa opção automaticamente.
Que linguagem você está usando?
fonte
Use a biblioteca TopShelf .
Crie um aplicativo de console e defina a configuração no seu Main
Para depurar seu serviço, basta pressionar F5 no visual studio.
Para instalar o serviço, digite cmd "console.exe install"
Você pode iniciar e interromper o serviço no gerenciador de serviços do Windows.
fonte
Eu acho que depende do sistema operacional que você estiver usando, o Vista é muito mais difícil de conectar aos Serviços, devido à separação entre as sessões.
As duas opções que usei no passado são:
Espero que isto ajude.
fonte
Eu gosto de poder depurar todos os aspectos do meu serviço, incluindo qualquer inicialização no OnStart (), enquanto ainda o executo com comportamento de serviço completo dentro da estrutura do SCM ... sem modo "console" ou "aplicativo".
Eu faço isso criando um segundo serviço, no mesmo projeto, para usar na depuração. O serviço de depuração, quando iniciado como de costume (ou seja, no plug-in MMC de serviços), cria o processo de host do serviço. Isso fornece um processo ao qual anexar o depurador, mesmo que você ainda não tenha iniciado seu serviço real. Após anexar o depurador ao processo, inicie o serviço real e você poderá entrar nele em qualquer lugar do ciclo de vida do serviço, incluindo OnStart ().
Como requer uma intrusão mínima de código, o serviço de depuração pode ser facilmente incluído no seu projeto de configuração de serviço e é facilmente removido do seu release de produção, comentando uma única linha de código e excluindo um único instalador do projeto.
Detalhes:
1) Supondo que você esteja implementando
MyService
, também crieMyServiceDebug
. Adicione ambos àServiceBase
matriz da seguinteProgram.cs
maneira:2) Adicione o serviço real E o serviço de depuração ao instalador do projeto:
Ambos os serviços (real e depuração) são incluídos quando você adiciona a saída do projeto de serviço ao projeto de instalação do serviço. Após a instalação, os dois serviços aparecerão no plug-in service.msc MMC.
3) Inicie o serviço de depuração no MMC.
4) No Visual Studio, conecte o depurador ao processo iniciado pelo serviço de depuração.
5) Inicie o serviço real e aproveite a depuração.
fonte
Quando escrevo um serviço, coloco toda a lógica de serviço em um projeto de DLL e crio dois "hosts" que chamam nessa DLL, um é um serviço do Windows e o outro é um aplicativo de linha de comando.
Uso o aplicativo de linha de comando para depuração e anexo o depurador ao serviço real apenas para erros que não consigo reproduzir no aplicativo de linha de comando.
Se você usar essa abordagem, lembre-se de que é necessário testar todo o código enquanto estiver executando em um serviço real, enquanto a ferramenta de linha de comando é uma boa ajuda para depuração, é um ambiente diferente e não se comporta exatamente como um serviço real.
fonte
Ao desenvolver e depurar um serviço do Windows, normalmente o executo como um aplicativo de console adicionando um parâmetro de inicialização / console e verificando isso. Torna a vida muito mais fácil.
fonte
Que tal Debugger.Break () na primeira linha?
fonte
Para depurar o Windows Services, eu combino o GFlags e um arquivo .reg criado pelo regedit.
Ou salve os seguintes trechos e substitua servicename.exe pelo nome do executável desejado.
debugon.reg:
debugoff.reg:
fonte
Para programação de rotina de pequenas coisas, eu fiz um truque muito simples para depurar facilmente meu serviço:
No início do serviço, verifico o parâmetro da linha de comandos "/ debug". Se o serviço for chamado com esse parâmetro, eu não faço a inicialização normal do serviço, mas inicio todos os ouvintes e apenas exibo uma caixa de mensagens "Depuração em andamento, pressione ok para finalizar".
Portanto, se meu serviço for iniciado da maneira usual, ele será iniciado como serviço; se for iniciado com o parâmetro / depuração da linha de comando, ele funcionará como um programa normal.
No VS, adicionarei / deparei como parâmetro de depuração e inicio o programa de serviço diretamente.
Dessa forma, eu posso depurar facilmente para a maioria dos pequenos problemas de tipo. Obviamente, algumas coisas ainda precisarão ser depuradas como serviço, mas para 99% isso é bom o suficiente.
fonte
fonte
Eu uso uma variação na resposta da JOP. Usando parâmetros da linha de comando, você pode definir o modo de depuração no IDE com propriedades do projeto ou através do gerenciador de serviços do Windows.
fonte
Para solucionar problemas no programa existente do Windows Service, use 'Debugger.Break ()', como sugeriram outros.
Para o novo programa Windows Service, sugiro usar o método de James Michael Hare http://geekswithblogs.net/BlackRabbitCoder/archive/2011/03/01/c-toolbox-debug-able-self-installable-windows-service-template- redux.aspx
fonte
Basta colocar seu almoço do depurador em qualquer lugar e anexar o Visualstudio na inicialização
Também é necessário iniciar o VS como Administatrator e permitir que um processo possa ser depurado automaticamente por um usuário diferente (conforme explicado aqui ):
fonte
Use o projeto C # do Modelo de Serviço do Windows para criar um novo aplicativo de serviço https://github.com/HarpyWar/windows-service-template
Existem modos de console / serviço detectados automaticamente, instalador / desinstalador automático do seu serviço e vários recursos mais usados estão incluídos.
fonte
Aqui está o método simples que eu usei para testar o serviço, sem métodos adicionais de "Depuração" e com testes de unidade VS integrados.
fonte
fonte
Você tem duas opções para fazer a depuração.
Por favor consulte ESTA publicação do blog que eu criei para o tópico.
fonte
Basta colar
em qualquer lugar no seu código.
Por exemplo ,
Será atingido
Debugger.Break();
quando você executar o seu programa.fonte
A melhor opção é usar o ' System.Diagnostics espaço para nome ' '.
Coloque seu código no bloco if else do modo de depuração e de liberação, como mostrado abaixo, para alternar entre o modo de depuração e de liberação no visual studio,
fonte