# Delphi: Como Desligar, Reiniciar e fazer Logoff no Windows (Guia Atualizado)

Em alguns projetos de automação, quiosques de autoatendimento (totens) ou sistemas de monitoramento em Delphi, é necessário ter o controle total sobre o sistema operacional, incluindo a capacidade de desligar ou reiniciar o computador diretamente pelo software.

No Windows moderno (Windows 10 e Windows 11), para realizar essas ações de forma segura e sem travamentos, precisamos interagir diretamente com a API do Windows (as famosas funções da WinAPI) e solicitar privilégios específicos de encerramento para a aplicação.

Neste artigo prático, você vai aprender a criar uma rotina robusta em Delphi para desligar, reiniciar ou fazer logoff no Windows de forma totalmente compatível com as versões atuais do sistema.


🔑 O Segredo dos Privilégios no Windows

O Windows protege o sistema contra desligamentos acidentais por softwares de terceiros. Por isso, antes de enviar o comando de desligamento, nossa aplicação precisa solicitar e obter o privilégio de segurança chamado SE_SHUTDOWN_NAME.

Se você tentar apenas disparar o comando sem essa validação de privilégios, a função falhará silenciosamente em sistemas modernos devido às restrições de controle de conta de usuário (UAC).


💻 O Código Definitivo (Compatível com Windows 7, 10 e 11)

Para implementar, crie uma função genérica. Ela utilizará as units nativas Winapi.Windows e System.SysUtils.

Adicione no seu código a seguinte procedure:

procedure ControlarEnergiaWindows(const Acao: Word);
var
  HandleToken: THandle;
  TokenPrivileges: TTokenPrivileges;
  RetornoComprimento: DWord;
begin
  // 1. Solicita o Token de Acesso para este processo para ajustar os privilégios
  if OpenProcessToken(GetCurrentProcess, TOKEN_ADJUST_PRIVILEGES or TOKEN_QUERY, HandleToken) then
  begin
    try
      // Obtém o LUID local para o privilégio de desligamento
      if LookupPrivilegeValue(nil, 'SeShutdownPrivilege', TokenPrivileges.Privileges[0].Luid) then
      begin
        TokenPrivileges.PrivilegeCount := 1; // Quantidade de privilégios a alterar
        TokenPrivileges.Privileges[0].Attributes := SE_PRIVILEGE_ENABLED;

        // Aplica o novo privilégio de desligamento ao nosso processo
        AdjustTokenPrivileges(HandleToken, False, TokenPrivileges, SizeOf(TTokenPrivileges), TokenPrivileges, RetornoComprimento);
      end;
    finally
      // Sempre fecha o handle de segurança aberto
      CloseHandle(HandleToken);
    end;
  end;

  // 2. Executa a ação desejada na API do Windows
  case Acao of
    1: // DESLIGAR (Force)
      ExitWindowsEx(EWX_SHUTDOWN or EWX_FORCE, SHTDN_REASON_MAJOR_OTHER);
     
    2: // REINICIAR (Force)
      ExitWindowsEx(EWX_REBOOT or EWX_FORCE, SHTDN_REASON_MAJOR_OTHER);
     
    3: // LOGOFF (Force)
      ExitWindowsEx(EWX_LOGOFF or EWX_FORCE, SHTDN_REASON_MAJOR_OTHER);
  end;
end;


🛠️ Como Usar no Seu Formulário

Com a procedure declarada no seu código, basta chamá-la associando aos eventos de cliques dos seus botões:

🔹 Para Desligar o Computador:

procedure TForm1.BtnDesligarClick(Sender: TObject);
begin
  if MessageDlg('Deseja realmente desligar o computador?', mtConfirmation, [mbYes, mbNo], 0) = mrYes then
  begin
    ControlarEnergiaWindows(1);
  end;
end;

🔹 Para Reiniciar o Computador:

procedure TForm1.BtnReiniciarClick(Sender: TObject);
begin
  if MessageDlg('Deseja realmente reiniciar o computador?', mtConfirmation, [mbYes, mbNo], 0) = mrYes then
  begin
    ControlarEnergiaWindows(2);
  end;
end;

🔹 Para Fazer Logoff (Trocar Usuário):

procedure TForm1.BtnLogoffClick(Sender: TObject);
begin
  ControlarEnergiaWindows(3);
end;


💡 Cuidados com o parâmetro "EWX_FORCE"

No código fornecido, utilizamos a diretiva EWX_FORCE junto com as ações. Essa flag força o encerramento de todos os aplicativos ativos no Windows que estejam travados ou com documentos não salvos.

Se o seu software roda em um ambiente corporativo, certifique-se de avisar o usuário para salvar o trabalho antes de disparar o comando, pois o Windows encerrará tudo sem exibir diálogos de confirmação externos.


💬 Participe da discussão!

Em qual tipo de sistema você utiliza esse controle de energia (totens, automação comercial, etc.)? Já teve problemas com o controle de privilégios em versões recentes do Windows?

Deixe seu comentário abaixo para que possamos trocar experiências!


Nenhum comentário:

Postar um comentário