PDA

Ver la Versión Completa : Hibernar o no hibernar, he ahí el dilema


Wellnic
23-01-2008, 19:34:55
Hola, ¿cómo se puede averiguar si en Windows está activada la hibernación? Hasta ahora lo averiguo comprobando si existe el fichero "hiberfil.sys", por ejemplo:


...
SetString(wh, WinDir, GetWindowsDirectory(WinDir, MAX_PATH));
wh:= ExtractFileDrive(wh)+'\hiberfil.sys';
...

If FileExist(wh) Then...


Pero no me parece la manera más adecuada. Digo yo que debería haber alguna función específica para ello...:)

maeyanes
23-01-2008, 20:00:24
Hola...

Revisa la función de la API: GetPwrCapabilities

http://msdn2.microsoft.com/en-us/library/aa372691(VS.85).aspx


Saludos...

Wellnic
23-01-2008, 22:42:07
El problema es que yo utilizo una versión de Delphi muuuy antigua, la 3 (del siglo pasado, vamos) y esa función no la reconoce :confused: A lo mejor hay que añadir algún módulo...

ixMike
23-01-2008, 23:04:45
El problema es que yo utilizo una versión de Delphi muuuy antigua, la 3 (del siglo pasado, vamos) y esa función no la reconoce :confused: A lo mejor hay que añadir algún módulo...

Hombre, tampoco es para ponerse así. Usamos la misma versión :). Será cuestión de probar con las típicas "uses" que tienen APIs de Windows (Windows, ShellApi, ShlObj...), pero si no dieras con ella, en el enlace te da la información suficiente como para que la puedas implementar tú mismo (me refiero la llamada a la API).


Salu2.


P.D.: Yo tengo D3 standar, ¿y tú?

Wellnic
24-01-2008, 00:22:18
La mía la adquirí por 995 pesetas hace unos once años, era la primera de una serie de fascículos sobre programación. Apuesto a que es tu mismo caso.

Para lo que hago es más que suficiente :) Y desde luego no me quejo, ni mucho menos. De hecho aún me viene grande :)

cHackAll
24-01-2008, 18:49:43
Hola, ¿cómo se puede averiguar si en Windows está activada la hibernación?Revisa el primer comentario de éste (http://www.clubdelphi.com/trucos/index.php?id=420) truco.

Saludos

dec
24-01-2008, 18:53:26
Hola,

Yo utilizo en cierto proyecto una función similar a esta:


function SystemCanHibernate(): boolean;
resourcestring
rsDll = 'powrprof.dll';
rsFunc = 'IsPwrHibernateAllowed';
type
TFunc = function: boolean; stdcall;
var
func: TFunc;
hDll: THandle;
begin
result := false;
hDll := LoadLibrary(PChar(rsDll));
if (hDll <> 0) then
try
@func := GetProcAddress(hDll, PChar(rsFunc));
result := Assigned(func) and func();
finally
FreeLibrary(hDll);
end;
end;


Esta otra función serviría para averiguar si el sistema puede suspenderse:


function SystemCanSuspend(): boolean;
resourcestring
rsDll = 'powrprof.dll';
rsFunc = 'IsPwrSuspendAllowed';
type
TFunc = function: boolean; stdcall;
var
func: TFunc;
hDll: THandle;
begin
result := false;
hDll := LoadLibrary(PChar(rsDll));
if (hDll <> 0) then
try
@func := GetProcAddress(hDll, PChar(rsFunc));
result := Assigned(func) and func();
finally
FreeLibrary(hDll);
end;
end;

cHackAll
24-01-2008, 19:54:31
Yo utilizo en cierto proyecto una función similar a esta...

:eek: han usado mi truco y le han aumentado "cosas"...

uses Windows;
function IsPwrHibernateAllowed: LongBool; external 'powrprof.dll';
var hToken: Cardinal;
begin
if OpenProcessToken(DWORD(-1), TOKEN_ADJUST_PRIVILEGES, hToken) then
AdjustTokenPrivileges(hToken, False, PTokenPrivileges(PChar(#1#0#0#0#19#0#0#0#0#0#0#0#2#0#0#0))^, 16, nil, PDWORD(0)^);
if not IsPwrHibernateAllowed then
MessageBox(0, 'No está habilitada la hibernación del sistema!', nil, MB_ICONEXCLAMATION)
else if not SetSystemPowerState(False, True) then
MessageBox(0, 'No se ha podido hibernar el equipo!', nil, MB_ICONEXCLAMATION);
end.

PD: tenemos que usar más la sección de trucos.

Saludos

Wellnic
24-01-2008, 19:58:34
Muchas gracias. Trataré de estudiar todas estas funciones, a ver si consigo entenderlas, porque yo no me conformo con copiar y pegar :)

Wellnic
16-05-2008, 20:11:10
Estas funciones, en realidad, no siempre detectan si se puede hibernar o no. Cuando tengo el MODEM encendido, por ejemplo, no se dan por enteradas de que no se puede hibernar el ordenador.

cHackAll
16-05-2008, 21:44:47
Otra cosa es que cuando se inicia el proceso de hibernado en modo NO crítico, el sistema envia a todas las colas de mensajes el mensaje WM_POWERBROADCAST, con la estructura PBT_APMQUERYSUSPEND, el cual puede retornar el valor BROADCAST_QUERY_DENY para suspender el intento de hibernación. Esto no significa que las anteriores APIs no sean las adecuadas.

Saludos (http://msdn.microsoft.com/en-us/library/aa373206(VS.85).aspx)

Wellnic
17-05-2008, 01:18:53
Sin embargo entiendo que esos mensajes se producen a posteriori, cuando es un poco "demasiado tarde". En la práctica no sirve de mucho saber que no se pudo hibernar, sería más útil saber si se podrá hibernar.

Debería existir una función que lo detectara a priori en todos los casos.

cHackAll
17-05-2008, 01:34:37
Al cancelarse la hibernación, la API SetSystemPowerState debería retornar false ó en su defecto algún GetLastError. Me podrías comentar el resultado de mi ejemplo con tu modem activo y el valor de GetLastError luego de la llamada a dicha API en caso de cancelacion?

Wellnic
17-05-2008, 02:03:51
Con el MODEM activo SetSystemPowerState da false y GetLastError da 0.

(Por cierto, es un MODEM USB).