unit LibPowerSystem;
interface
uses
Windows, SysUtils, TlHelp32, Forms, WinBase, Messages,
LibProcessInfo;
procedure SYSTEM_Reboot(Force : Boolean);
procedure SYSTEM_PowerOff(Force : Boolean);
procedure SYSTEM_LogOff;
// 2010.11.25 JAZZ 추가
// Deny 횟수만큼 Allow 해야 실제로 Allow된다. 단 AllowForce인 경우 무조건 Allow.
procedure SYSTEM_DenySuspendMode;
procedure SYSTEM_AllowSuspendMode(const AllowForce: Boolean = FALSE);
function SYSTEM_ON_WM_POWERBROADCAST(var M: TMessage) : Boolean; // 메인 폼에서 메세지 Dispatcher에 이 함수 연결할것
// 2014.11.28 JAZZ 추가
function SYSTEM_Suspend(DisableWakeEvent: Boolean = FALSE): Boolean; // 절전 모드
function SYSTEM_Hibernate(DisableWakeEvent: Boolean = FALSE): Boolean; // 최대 절정 모드
{
=============================================================
Samples
=============================================================
type TForm1 = Class(TForm)
...
procedure ON_WM_POWERBROADCAST(var M:TMessage); message WM_POWERBROADCAST;
...
end;
...
procedure TForm1.ON_WM_POWERBROADCAST(var M: TMessage);
begin
if not SYSTEM_ON_WM_POWERBROADCAST(M) then begin
inherited;
end;
end;
=============================================================
}
{$EXTERNALSYM SetSuspendState}
function SetSuspendState(Hibernate, ForceCritical, DisableWakeEvent: BOOLEAN): BOOLEAN; stdcall;
[System] Process Information Library
unit LibProcessInfo; interface uses Windows, WinBase, SysUtils, TlHelp32, PSAPI; type TProcessFindProc = function (ProcessInfo : PProcessEntry32; UserPara : Pointer) : BOOL; stdcall; TModuleFindProc..
jazz16.tistory.com
const
powrprof_lib = 'powrprof.dll';
function SetSuspendState; external powrprof_lib name 'SetSuspendState';
const
SystemProcessList_NT : Array[0..5] of String =
( 'EXPLORER.EXE', 'SVCHOST.EXE', 'CISVC.EXE', 'CIDAEMON.EXE',
'SERVICES.EXE', 'WINLOGON.EXE'
);
SystemProcessList_98 : Array[0..10] of String =
( 'EXPLORER.EXE', 'MPREXE.EXE', 'WMIEXE.EXE', 'MSTASK.EXE',
'SYSTRAY.EXE', 'INTERNAT.EXE', 'TASKMON.EXE', 'IMEJP98M.EXE',
'USER.EXE', 'MSGSRV32.EXE', 'KB891711.EXE'
);
function SYSTEM_ActiveDesktopEnabled : Boolean;
begin
Result := FindWindowEx(
FindWindowEx(
FindWindowEx(GetDesktopWindow, 0, 'Progman', nil),
0, 'SHELLDLL_DefView', nil),
0, 'Internet Explorer_Server', nil) <> 0;
end;
const
DEBUG_MSG_BOX = FALSE;
procedure SYSTEM_KillProcessByFilter(ExcludeFileList : Array of String;
const ExcludeNonExeImage : Boolean = TRUE;
const UserProcessOnlyOnNT : Boolean = TRUE);
var
Process32 : TProcessEntry32;
SHandle : THandle; // the handle of the Windows object
RT : BOOL;
Ln, I : Integer;
EX : Array of String;
FileName : String;
CPID : DWORD;
{$IF DEBUG_MSG_BOX}
DL : String;
{$IFEND}
begin
{$IF DEBUG_MSG_BOX}
DL := '';
{$IFEND}
Ln := Length(ExcludeFileList);
SetLength(EX, Ln);
if Ln > 0 then for I:=0 to Ln-1 do EX[I] := UpperCase(ExtractFileName(ExcludeFileList[I]));
CPID := GetCurrentProcessID;
Process32.dwSize := SizeOf(TProcessEntry32);
SHandle := CreateToolHelp32Snapshot(TH32CS_SNAPPROCESS, 0);
RT := Process32First(SHandle, Process32);
while RT do begin
RT := Process32.th32ProcessID <> CPID;
if RT then FileName := UpperCase(ExtractFileName(Process32.szExeFile));
if RT and ExcludeNonExeImage then RT := ExtractFileExt(FileName) = '.EXE';
if RT and (Ln > 0) then for I:=0 to Ln-1 do if EX[I] = FileName then RT := FALSE;
{$IF DEBUG_MSG_BOX}
if RT then begin
if KillProcess(Process32.th32ProcessID, UserProcessOnlyOnNT)
then DL := DL + #13 + 'SUCC : ' + Process32.szExeFile
else DL := DL + #13 + 'FAIL : ' + Process32.szExeFile;
end;
{$ELSE}
if RT then KillProcess(Process32.th32ProcessID, UserProcessOnlyOnNT);
{$IFEND}
RT := Process32Next(SHandle, Process32);
end;
CloseHandle(SHandle);
{$IF DEBUG_MSG_BOX}
MessageBox(0, PChar(DL), 'KillProcess Report', MB_OK);
{$IFEND}
end;
function SYSTEM_AccessNTPrivilege(Prvlg : PChar; ModeEnable : Boolean) : Boolean;
var
Token : THandle;
PRV, nPRV : TTokenPrivileges;
begin
PRV.PrivilegeCount := 1;
if ModeEnable
then PRV.Privileges[0].Attributes := SE_PRIVILEGE_ENABLED
else PRV.Privileges[0].Attributes := 0;
Result := OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES or TOKEN_QUERY, Token)
and LookupPrivilegeValue('', Prvlg, PRV.Privileges[0].LUID)
and Windows.AdjustTokenPrivileges(Token, False, PRV, SizeOf(TOKEN_PRIVILEGES), @nPRV, nPRV.PrivilegeCount);
end;
function SYSTEM_GetShutdownPrivilegeNT(ModeEnable : Boolean) : Boolean;
const
SE_SHUTDOWN_NAME = 'SeShutdownPrivilege';
begin
Result := SYSTEM_AccessNTPrivilege(SE_SHUTDOWN_NAME, ModeEnable);
end;
procedure SYSTEM_RebootNT(Force : Boolean);
var
FLAG : DWORD;
begin
if not SYSTEM_GetShutdownPrivilegeNT(TRUE) then Exit;
FLAG := EWX_SHUTDOWN or EWX_REBOOT;
if Force then begin
if SYSTEM_ActiveDesktopEnabled
then SYSTEM_KillProcessByFilter(SystemProcessList_NT, TRUE, TRUE)
else FLAG := FLAG or EWX_FORCE;
end;
ExitWindowsEx(FLAG, 0);
end;
procedure SYSTEM_Reboot98(Force : Boolean);
var
FLAG : DWORD;
begin
FLAG := EW_REBOOTSYSTEM;
if Force then SYSTEM_KillProcessByFilter(SystemProcessList_98, TRUE, TRUE);
Application.ProcessMessages;
Sleep(100);
Application.ProcessMessages;
ExitWindowsEx(FLAG, 0);
Application.ProcessMessages;
Sleep(100);
Application.ProcessMessages;
// Halt(0);
end;
procedure SYSTEM_Reboot(Force : Boolean);
begin
if (Win32Platform = VER_PLATFORM_WIN32_NT)
then SYSTEM_RebootNT(Force)
else SYSTEM_Reboot98(Force);
end;
procedure SYSTEM_PowerOffNT(Force : Boolean);
var
FLAG : DWORD;
begin
if not SYSTEM_GetShutdownPrivilegeNT(TRUE) then Exit;
FLAG := EWX_SHUTDOWN or EWX_POWEROFF;
if Force then begin
if SYSTEM_ActiveDesktopEnabled
then SYSTEM_KillProcessByFilter(SystemProcessList_NT, TRUE, TRUE)
else FLAG := FLAG or EWX_FORCE;
end;
ExitWindowsEx(FLAG, 0);
end;
procedure SYSTEM_PowerOff98(Force : Boolean);
var
FLAG : DWORD;
begin
FLAG := $0040 or EWX_SHUTDOWN;
if Force then SYSTEM_KillProcessByFilter(SystemProcessList_98, TRUE, TRUE);
Application.ProcessMessages;
Sleep(100);
Application.ProcessMessages;
ExitWindowsEx(FLAG, 0);
Application.ProcessMessages;
Sleep(100);
Application.ProcessMessages;
// Halt(0);
end;
procedure SYSTEM_PowerOff(Force : Boolean);
begin
if (Win32Platform = VER_PLATFORM_WIN32_NT)
then SYSTEM_PowerOffNT(Force)
else SYSTEM_PowerOff98(Force);
end;
procedure SYSTEM_LogOffNT;
begin
ExitWindowsEx(EWX_LOGOFF, 0);
end;
procedure SYSTEM_LogOff98;
begin
ExitWindowsEx($0040 or EWX_LOGOFF, 0);
end;
procedure SYSTEM_LogOff;
begin
if (Win32Platform = VER_PLATFORM_WIN32_NT)
then SYSTEM_LogOffNT()
else SYSTEM_LogOff98();
end;
// 2010.11.25 JAZZ 추가
// Deny 횟수만큼 Allow 해야 실제로 Allow된다.
var
__DenySuspendTag : Integer;
procedure __LockPowerSuspend;
begin
// 대기모드/최대절전모드 진입금지
try SetThreadExecutionState(ES_CONTINUOUS or ES_SYSTEM_REQUIRED or ES_AWAYMODE_REQUIRED { or ES_DISPLAY_REQUIRED });
except
end;
end;
procedure __ReleasePowerSuspend;
begin
// 대기모드/최대절전모드 진입허용
try SetThreadExecutionState(ES_CONTINUOUS);
except
end;
end;
procedure SYSTEM_DenySuspendMode;
begin
// 굳이 크리티컬 처리를 할 필요는 없을듯... 쓰레드내에서 호출하지 마라!!!
Inc(__DenySuspendTag);
if __DenySuspendTag = 1 then begin
__LockPowerSuspend();
end;
end;
procedure SYSTEM_AllowSuspendMode(const AllowForce: Boolean = FALSE);
begin
if __DenySuspendTag < 1 then Exit;
if AllowForce
then __DenySuspendTag := 0
else Dec(__DenySuspendTag);
if __DenySuspendTag = 0 then begin
__ReleasePowerSuspend();
end;
end;
function SYSTEM_ON_WM_POWERBROADCAST(var M: TMessage) : Boolean; // 메인 폼에서 메세지 Dispatcher에 이 함수 연결할것
const
PBT_APMQUERYSUSPEND = $00000000;
begin
RESULT := FALSE;
case M.WParam of
// Vista 이상에서는 들어오지 않는다. ( SetThreadExecutionState 사용 )
PBT_APMQUERYSUSPEND : begin
if __DenySuspendTag > 0
then M.Result := BROADCAST_QUERY_DENY
else M.Result := Integer(TRUE);
RESULT := TRUE;
end;
end;
end;
// 2014.11.28 JAZZ 추가
function SYSTEM_Suspend(DisableWakeEvent: Boolean = FALSE): Boolean; // 절전 모드
begin
RESULT := FALSE;
if (Win32Platform <> VER_PLATFORM_WIN32_NT) then Exit;
if not SYSTEM_GetShutdownPrivilegeNT(TRUE) then Exit;
RESULT := SetSuspendState(FALSE, TRUE, DisableWakeEvent);
end;
// 2014.11.28 JAZZ 추가
function SYSTEM_Hibernate(DisableWakeEvent: Boolean = FALSE): Boolean; // 최대 절정 모드
begin
RESULT := FALSE;
if (Win32Platform <> VER_PLATFORM_WIN32_NT) then Exit;
if not SYSTEM_GetShutdownPrivilegeNT(TRUE) then Exit;
RESULT := SetSuspendState(TRUE, TRUE, DisableWakeEvent);
end;
end.
'Libraries > Delphi Library' 카테고리의 다른 글
[String] Wide String Library (0) | 2022.06.24 |
---|---|
[String] String Library (0) | 2022.06.24 |
[System] OS Version Library (0) | 2022.06.23 |
[OLE] OLE Command Library (0) | 2022.06.23 |
[IPC] Mutex Library (0) | 2022.06.22 |