Como determinar, em código, quanto tempo a máquina fica travada?
Outras idéias fora do C # também são bem-vindas.
Gosto da ideia do serviço Windows (e aceitei-a) pela simplicidade e limpeza, mas infelizmente não acho que funcione para mim neste caso em particular. Eu queria executá-lo em minha estação de trabalho no trabalho, em vez de em casa (ou além de casa, suponho), mas está bloqueado com muita força por cortesia do DoD. Essa é parte da razão pela qual estou fazendo o meu próprio, na verdade.
Vou escrever de qualquer maneira e ver se funciona. Obrigado a todos!
Eu criaria um serviço do Windows (um tipo de projeto do Visual Studio 2005) que lida com o evento OnSessionChange conforme mostrado abaixo:
O que e como você registra a atividade naquele ponto é com você, mas um serviço do Windows fornece acesso rápido e fácil aos eventos do Windows, como inicialização, desligamento, login / saída, junto com os eventos de bloqueio e desbloqueio.
fonte
A solução abaixo usa a API Win32. OnSessionLock é chamado quando a estação de trabalho está bloqueada e OnSessionUnlock é chamado quando é desbloqueado.
fonte
Eu sei que esta é uma questão antiga, mas encontrei um método para obter o estado de bloqueio para uma determinada sessão.
Encontrei minha resposta aqui, mas estava em C ++, então traduzi o máximo que pude para C # para obter o estado de bloqueio.
Então aqui vai:
Nota: O código acima foi extraído de um projeto muito maior, então se eu perdi um pouco, desculpe. Não tenho tempo para testar o código acima, mas pretendo voltar em uma ou duas semanas para verificar tudo. Só postei agora porque não queria esquecer de fazer.
fonte
if (session_info_ex.Level != 1)
- se a condição for verdadeira, a memória não será liberada. 2. se session_info_ex.Level! = 1, você não deve fazer isso:Marshal.PtrToStructure<WTSINFOEX>(ppBuffer);
porque o tamanho do buffer retornado pode ser diferente do tamanho de WTSINFOEXUInt32 Reserved;
vez disso, você deve definir a estruturaWTSINFOEX_LEVEL1
completamente. Nesse caso, o compilador fará o preenchimento (alinhamento) correto dos campos dentro da estrutura. 4. A funçãoWTSFreeMemoryEx
é mal utilizada aqui.WTSFreeMemory
deve ser usado em seu lugar.WTSFreeMemoryEx
destina-se a liberar memória depoisWTSEnumerateSessionsEx
.CharSet = CharSet.Auto
deve ser usado em todos os atributos.Se você estiver interessado em escrever um serviço do Windows para "encontrar" esses eventos, o topshelf (a biblioteca / estrutura que torna a escrita dos serviços do Windows muito mais fácil) tem um gancho.
e agora o código para conectar o serviço topshelf à interface / concreto acima
Tudo a seguir é uma configuração de prateleira "típica" ... exceto por 2 linhas que marquei como
/ * ESTA É LINHA MÁGICA * /
Isso é o que faz o método SessionChanged disparar.
Eu testei isso com o Windows 10 x64. Travei e destravei minha máquina e obtive o resultado desejado.
Meu packages.config para fornecer dicas sobre as versões:
fonte
x.EnableSessionChanged();
em conjunto com aServiceSessionChange
implementação da interface se você implementouServiceControl
e não criou a implicação da instância da classe de serviço. Gostox.Service<ServiceImpl>();
. Você tem que implementarServiceSessionChange
naServiceImpl
aula:class ServiceImpl : ServiceControl, ServiceSessionChange
NOTA : Esta não é uma resposta, mas uma (contribuição) para a resposta de Timothy Carter , porque minha reputação não me permite comentar até agora.
Caso alguém tente o código da resposta de Timothy Carter e não o faça funcionar imediatamente em um serviço do Windows, há uma propriedade que precisa ser definida
true
no construtor do serviço. Basta adicionar a linha no construtor:E certifique-se de não definir essa propriedade após o serviço ser iniciado, caso contrário, um
InvalidOperationException
será lançado.fonte
Abaixo está o código 100% funcional para descobrir se o PC está bloqueado ou não.
Antes de usar isso, use o namespace
System.Runtime.InteropServices
.fonte