Ir para conteúdo
Fórum Script Brasil
  • 0

Hibernação


Paulo Nobre

Pergunta

Gostaria de saber como, via programação, poderia saber se o computador vai hibernar.

Mais objetivamente: tenho um programa que tem um timer.

Gostaria que o programa ao perceber que o computador vai hibernar desative este timer.

Isto é possível?

Link para o comentário
Compartilhar em outros sites

  • Respostas 67
  • Created
  • Última resposta

Top Posters For This Question

Posts Recomendados

  • 0

Aqui também deu erro de Access Violation, pensei que fosse por causa que estivesse rodando diretamente do Delhpi (sessão de debug ativa). você tentou rodar independentemente do Delphi?

Também aparece o erro de violação :(

E quanto a ele não mostrar a mensagem (hibernando), é porque a mensagem não é enviada ao próprio programa que solicitou a suspenção, somente é enviada quando é retomada a execução.

Não entendi. Se o programa está rodando a função naõ vai interceptar a emnsagem de hibernação e portanto não teria que retornar dizendo que vai hibernar?

Link para o comentário
Compartilhar em outros sites

  • 0

É, o caso do access violation eu realmente não sei porque ocorre, eu teria que estudar mais sobre isso.

Não entendi. Se o programa está rodando a função naõ vai interceptar a emnsagem de hibernação e portanto não teria que retornar dizendo que vai hibernar?

E eu não entendí o que você não entendeu. Se um programa solicitou a suspensão, não há motivo para o windows perguntar para o mesmo se pode suspender o processo porque ele já sabe que o programa deve aceitar. Nesse caso a mensagem é enviada mas não com wParam igual a PBT_APMQUERYSUSPEND, somente com wParam igual a PBT_APMSUSPEND. Tente verificar esse ultimo parametro pra ver se ele avisa. Falei?

Link para o comentário
Compartilhar em outros sites

  • 0

E eu não entendí o que você não entendeu. Se um programa solicitou a suspensão, não há motivo para o windows perguntar para o mesmo se pode suspender o processo porque ele já sabe que o programa deve aceitar. Nesse caso a mensagem é enviada mas não com wParam igual a PBT_APMQUERYSUSPEND, somente com wParam igual a PBT_APMSUSPEND. Tente verificar esse ultimo parametro pra ver se ele avisa. Falei?

Entendi!! :)

Link para o comentário
Compartilhar em outros sites

  • 0

Ok, Thales.

Você está correto.

O botão que chama a hibernação via SetSuspendState, está no próprio programa, que tinha

a possível interceptação da mensagem. Como ele mesmo manda hibernar, não teria sentido interceptar dele mesmo.

Link para o comentário
Compartilhar em outros sites

  • 0

Ahhhhhhh, Paulo, tem mais um detalhe: Só é necessário o result ser igual a 1 no caso da mensagem ser PBT_QUERYSUSPEND, onde o 1 significa que você aceitou a suspensão e 0 que não. Quando a mensagem é PBT_RESUMESUSPEND não há retorno nenhum, então nesse caso não deve ser executado o comando msg.result:=1;. Certo? Pode ser que por uma razão inexplicavel isso até resolva o access violation.

Link para o comentário
Compartilhar em outros sites

  • 0

Vale fazer certos testes, por exemplo, rode duas cópias desse executável, e mande hibernar por uma delas. Se só a que mandou hibernar der o erro no retorno da hibernação é porque tem a ver com a chamada da função, ou seja, o windows trata o processo que solicitou a hibernação diferentemente dos demais. Depois de constatado isso, deveremos quebrar a cabeça lendo a documentação do windows e do Delphi. Vou ver se descubro esse erro e posto mais tarde, caso descubra. Pode demorar.

Link para o comentário
Compartilhar em outros sites

  • 0
Sem stress e sem pressa.

Beleza

ok!

Se for de alguma utilidade, existe a função a seguir que também faz a hibernação, só que com essa parece que o processo precisa de previlégios concedidos pelo sistema operacional para conseguir a hibernação, do contrário a hibernação falha.

function SetSystemPowerState(fSuspend, fForce : boolean) : Boolean;

fSuspend true suspende, false hiberna.

fForce true manda mensagem PBT_APMSUSPEND para todos os processos e força suspensão, do contrário manda PBT_APMQUERYSUSPEND para processos e pede por permissão para suspender.

O retorno é não-zero se falhar e zero se obtiver sucesso.

Link para o comentário
Compartilhar em outros sites

  • 0

Vamos bater o record mundial de posts num forum

Não passamos nem da décima página!! :)

Talvez com essa função não ocorra o access violation.

Mas, neste caso haveria problema caso o usuário não fosse o administrador, não é?

Link para o comentário
Compartilhar em outros sites

  • 0

Tem uma função que ajusta os privilégios do processo, mas enquanto isso tenta fazer com essa função pra ver se ocorre o erro, caso não consiga a hibernação, avise que eu detalharei a função dos privilégios aqui.

Link para o comentário
Compartilhar em outros sites

  • 0

Então deve estar pegando o problema dos privilégios. Mas o ruims é que é preciso ter privilégios para habilitar algum privilégio com a função que mencionei, então acho que é preciso ser administrador do sistema mesmo para conseguir isso.

Caso tenha curiosidade de olhar a documentação do windows no site da microsoft, o nome da função é AdjustTokenPrivileges. Seu uso é bem complicadinho. Tem que se habilitar o privilégio SE_SHUTDOWN_NAME para poder fazer a hibernação. Por enquanto não cabe tecer maiores detalhes sobre ela. Vou fazer vários testes aqui, e se por acaso surgir a necessidade da utilização dela, entraremos em maiores detalhes.

Agora tenho que sair. Amanhã agente chega aos 90 posts.

Link para o comentário
Compartilhar em outros sites

  • 0

Fala Paulo. Vai trabalhar hoje?

É o seguinte. Quando eu descobrí que a função SetSuspendState estava numa dll eu usei o jeito mais fácil de importar a função como é feito na unit windows para importar a api, que é carregar a dll quando inicia-se a execução do programa. Ai eu hibernei meu computador umas 300 vezes fazendo testes por causa daquele erro. Mas se eu tivesse feito uma buscazinha no bom e velho google, eu teria achado mais rápido. No site do Torry eu achei um exemplo dessa função, só que usando as fuções GetModuleHandle, GetProcAddress e LoadLibrary que são usadas para chamar a dll somente na hora que for ser usada a função, depois é fechada. Desse jeito não ocorreu o erro. Com certeza deve ser alguma coisa a ver com o acesso a dll depois da volta da hibernação, pode ser que precise ser aberta novamente ou coisa parecida. Aí está o código ->

var
  _SetSuspendState: function (Hibernate, ForceCritical, DisableWakeEvent: BOOL): BOOL
  stdcall = nil;

  function LinkAPI(const module, functionname: string): Pointer; forward;

function SetSuspendState(Hibernate, ForceCritical,
  DisableWakeEvent: Boolean): Boolean;
begin
  if not Assigned(_SetSuspendState) then
    @_SetSuspendState := LinkAPI('POWRPROF.dll', 'SetSuspendState');
  if Assigned(_SetSuspendState) then
    Result := _SetSuspendState(Hibernate, ForceCritical,
      DisableWakeEvent)
  else
    Result := False;
end;

function LinkAPI(const module, functionname: string): Pointer;
var
  hLib: HMODULE;
begin
  hLib := GetModulehandle(PChar(module));
  if hLib = 0 then
    hLib := LoadLibrary(PChar(module));
  if hLib <> 0 then
    Result := getProcAddress(hLib, PChar(functionname))
  else
    Result := nil;
end;

// Example Call:
// Beispielaufruf:

procedure TForm1.Button1Click(Sender: TObject);
begin
  SetSuspendState(True, False, False);
end;

Link para o comentário
Compartilhar em outros sites

  • 0

Opa, Paulo. Desculpe a ignorância. Eu sabia que todos os processos externos tem que ser chamados com stdcall, mas não o coloquei porque também não estavam presentes na implementation da unit windows, mas depois fui ver que estavam na interface, portanto do outro jeito também funciona se for declarado dessa maneira->

function setsuspendstate(a,b,c:boolean) : integer; stdcall; external 'powrprof.dll' name 'SetSuspendState';

Link para o comentário
Compartilhar em outros sites

  • 0

Só para complementar as informações fornecidas pelos colegas deste tópico; se alguém tiver alguma dúvida quanto às funções, mensagens ou constantes referentes hibernação, shutdown, boot ou qualquer outra coisa ligada à power management, vocês podem obtê-las no site oficial da Microsoft:

http://msdn.microsoft.com/library/default....t_reference.asp

Espero ter ajudado.

Link para o comentário
Compartilhar em outros sites

  • 0

Fala Paulo. Vai trabalhar hoje?

Fala Thales. Vou trabalhar meio expediente.

Mais tarde vou testar.

Mas, agora tenho certeza que vai funcionar.

Só para complementar as informações fornecidas pelos colegas deste tópico; se alguém tiver alguma dúvida quanto às funções, mensagens ou constantes referentes hibernação, shutdown, boot ou qualquer outra coisa ligada à power management, vocês podem obtê-las no site oficial da Microsoft:

Valeu KMKG, complementou bem!

Então, é aqui que estão os segredos né?

Link para o comentário
Compartilhar em outros sites

  • 0
Fala Thales. Vou trabalhar meio expediente.

Mais tarde vou testar.

Mas, agora tenho certeza que vai funcionar.

Espero que você tenha visto o meu post sobre o stdcall, e que não é preciso usar esse código do site do torry.

Só para complementar as informações fornecidas pelos colegas deste tópico; se alguém tiver alguma dúvida quanto às funções, mensagens ou constantes referentes hibernação, shutdown, boot ou qualquer outra coisa ligada à power management, vocês podem obtê-las no site oficial da Microsoft:

Eu comentei isso num outro post. É no site da microsoft que eu encontro todas essas informações sobre funções do windows. E a mesma documentação também pode ser encontrada na ajuda do Delphi 2006.

Link para o comentário
Compartilhar em outros sites

Participe da discussão

Você pode postar agora e se registrar depois. Se você já tem uma conta, acesse agora para postar com sua conta.

Visitante
Responder esta pergunta...

×   Você colou conteúdo com formatação.   Remover formatação

  Apenas 75 emoticons são permitidos.

×   Seu link foi incorporado automaticamente.   Exibir como um link em vez disso

×   Seu conteúdo anterior foi restaurado.   Limpar Editor

×   Você não pode colar imagens diretamente. Carregar ou inserir imagens do URL.




  • Estatísticas dos Fóruns

    • Tópicos
      152,1k
    • Posts
      651,8k
×
×
  • Criar Novo...