Ola Pessoal,Estou tirando a poeira do blog trazendo um assunto que me queimou uns bons neuronios nestes ultimos dias.Estou desenvolvendo uma aplicacao em C# com .NET4 do tipo WindowsService que ira realizar diversas funcoes em um computador rodando Windows. Uma destas funcoes e registrar os logons e logoffs dos usuarios que utilizarem tais computadores em um banco de dados SQL Server remoto para posterior consulta e auditoria.Pesquisando na web, encontrei diversas formas de codificar a captura destes eventos. Enquanto algumas se mostraram muito simples, outras eram bem complexas e cheias de codigo. Por fim, elas nao apresentaram o resultado como eu gostaria de visualizar.Depois de alguns dias escovando bit, cheguei a uma solucao utilizando um pouco de tudo que li nesses dias. O resultado eu gostaria de compartilhar com voces e, caso conhecam uma forma mais simples, nao deixem de postar.Afinal de contas, o blog foi criado para compartilharmos informacoes.Vamos entao a minha solucao:Toda classe derivada de ServiceBase possui a propriedade CanHandleSessionChangeEvent que quando definida como true, faz com que a classe derivada seja notificada caso haja alteracoes nas sessoes do Windows.Para tratar as notificacoes, devemos implementar o seguinte evento:A estrutura SessionChangeDescription possui 2 propriedades:Reason: descreve o tipo do evento (SessionLogon, SessionLogoff, RemoteConnect, RemoteDisconnect, SessionLock, SessionUnlock, dentre outros);SessionId: contem o numero da sessao em que o evento ocorreu (1, 2, 3, ...).Ate aqui foi sopinha no mel...A coisa comecou a complicar quando tentei descobrir qual era o usuario conectado na sessao do evento e descobri que no .NET nao ha uma forma "nativa" de fazer isso. Nem uma classe, metodo, evento, nada... Pelo menos, eu nao encontrei. E olha que revirei varios links do Google.O maximo que encontrei, foi o pessoal utilizando APIs de Terminal Services com codigos extremamente grandes fazendo chamadas a DLLs externas e que ainda sim, nao traziam o resultado que eu queria: Listavam os usuarios conectados, mas nao as sessoes. Ou eu nao fiz a codificacao direita ou deixei algo passar despercebido ou eu sou muito burro mesmo, mas enfim... Nao fui muito feliz com o lance das APIs. Alem do que, parece que essas APIs sao compativeis apenas com o Vista ou superior e eu preciso que o codigo rode tambem no XP. E o XP ainda nao morreu por aqui...Foi entao que voltei minha atencao a uma tecnologia que tenho utilizado nos ultimos anos e que tem me ajudado bastante: Windows Management Instrumentation ou simplesmente WMI.Pesquisando as classes do namespace root\CIMv2 encontrei a classe Win32_Process que lista os processos atualmente em execucao no computador e, ao selecionar um processo especifico, eu tenho a propriedade SessionId que mostra em qual sessao o processo esta sendo executado. E para minha alegria esta mesmissima classe possui um metodo chamado GetOwner que retorna o nome do usuario que esta executando aquele processo... Bingo! Bastava agora encontrar uma forma de filtrar os processos. E minha solucao para todo este caos foi a seguinte:Antes de mais nada, adicione System.Management a lista de referencias do seu projeto.Criei uma estrutura simples para armazenar as sessoes de usuario e declarei-a no escopo do meu servico:Criei