벤자민의 블로그 2기 시작
2023년 6월 13일 갑작스러운 부친상을 격고나서 무언가를 한다라는 것에서 거의 손을 대지 않고 있었네요. 슬프다거나 그런 감정보다는 그냥 무언가 빠져버린
시스템 셧다운
Shutdown the (local or remote) computer (with delay)
function TimedShutDown(Computer: string; Msg: string; Time: Word; Force: Boolean; Reboot: Boolean): Boolean;
var
rl: Cardinal;
hToken: Cardinal;
tkp: TOKEN_PRIVILEGES;
begin
//get user privileges to shutdown the machine, we are talking about win nt and 2k here
if not OpenProcessToken(GetCurrentProcess, TOKEN_ADJUST_PRIVILEGES or TOKEN_QUERY, hToken) then
ShowMessage('Cannot open process token.')
else
begin
if LookupPrivilegeValue(nil, 'SeShutdownPrivilege', tkp.Privileges[0].Luid) then
begin
tkp.Privileges[0].Attributes := SE_PRIVILEGE_ENABLED;
tkp.PrivilegeCount := 1;
AdjustTokenPrivileges(hToken, False, tkp, 0, nil, rl);
if GetLastError ERROR_SUCCESS then
ShowMessage('Error adjusting process privileges.');
end
else
ShowMessage('Cannot find privilege value.');
end;
Result := InitiateSystemShutdown(PChar(Computer), PChar(Msg), Time, Force, Reboot)
end;
Prevent Windows shutdown until files saved
Windows가 종료 될 때 열려있는 모든 응용 프로그램에 WM_QueryEndSession이라는 메시지를 보냅니다. Delphi 애플리케이션에서이 메시지를 감지하고 적절한 조치를 취하려면 메시지 처리기를 작성하십시오. 해당 메시지 처리기의 정의를 응용 프로그램의 기본 양식에 대한 유닛의 개인 섹션에 두십시오 (아래 참조).
또한 데이터를 저장할지 여부를 나타내는 부울 (논리) 변수, 예를 들어 DataToBeSaved가 필요합니다. 프로그램 시작시와 데이터를 저장할 때마다이 변수를 False로 설정하십시오. 데이터가 변경 될 때마다 True로 설정하십시오. private 섹션에서 변수를 선언하겠습니다.
private
{ Private declarations }
DataToBeSaved: Boolean;
procedure WMQueryEndSession(var Msg: TWMQueryEndSession);
message WM_QueryEndSession; // detect Windows shutdown message
procedure SaveData; // routine to save data to disk
// ...and so on
In the implementation section of the unit, add the following code:
// If necessary (if DataToBeSaved is True), delay the closing of Windows until
// your data are saved
procedure TForm1.WMQueryEndSession(var Msg: TWMQueryEndSession);
begin
if DataToBeSaved then
if MessageDlg('Windows is shutting down! First save data changes?',
mtConfirmation, [mbYes, mbNo], 0) = mrYes then begin
Msg.Result := 0; // disallow Windows from shutting down
SaveData;
end;
Msg.Result := 1; // allow Windows shutdown
end;
// Set DataToBeSaved to False after saving data
procedure TForm1.SaveData;
begin
// Save data to disk files
// ...
DataToBeSaved := False;
end;
// At the start of the program, DataToBeSaved must be False
procedure TForm1.FormCreate(Sender: TObject);
begin
DataToBeSaved := False;
end;
데이터가 변경 될 때마다 DataToBeSaved을 True로 설정하는 것을 잊지 마십시오.
응용 프로그램이 실행되는 동안 Windows가 닫힐 때 자동으로 데이터를 저장하려면 'Windows가 종료 중입니다!'라는 질문이있는 메시지 대화 상자를 생략하십시오! 먼저 데이터 변경 사항을 저장 하시겠습니까? ' 메시지 처리기의 코드는 다음과 같습니다.
procedure TForm1.WMQueryEndSession(var Msg: TWMQueryEndSession);
begin
if DataToBeSaved then begin
Msg.Result := 0; // stop Windows from shutting down
SaveData;
end;
Msg.Result := 1; // allow Windows shutdown
end;
How do I manipulate the computer (shutdown, restart, etc)
To shutdown the system:
procedure machine_shutdown;
const
SE_SHUTDOWN_NAME = 'SeShutdownPrivilege';
begin
NTSetPrivilege(SE_SHUTDOWN_NAME, True);
ExitWindowsEx(EWX_SHUTDOWN or EWX_FORCE, 0);
end;
This code restarts a computer:
procedure machine_restart;
const
SE_SHUTDOWN_NAME = 'SeShutdownPrivilege';
begin
NTSetPrivilege(SE_SHUTDOWN_NAME, True);
ExitWindowsEx(EWX_REBOOT or EWX_FORCE, 0);
end;
This code logs off the current user:
procedure machine_logoff;
const
SE_SHUTDOWN_NAME = 'SeShutdownPrivilege';
begin
NTSetPrivilege(SE_SHUTDOWN_NAME, True);
ExitWindowsEx(EWX_LOGOFF or EWX_FORCE, 0);
end;
This code powers down the system. This is distinguished from the shut down command in that it will power off the system, while the shut down command will just put the computer to a point where it can be turned off.
This code powers down the system:
procedure machine_poweroff;
const
SE_SHUTDOWN_NAME = 'SeShutdownPrivilege';
begin
if IsPwrShutdownAllowed then
begin
NTSetPrivilege(SE_SHUTDOWN_NAME, True);
ExitWindowsEx(EWX_POWEROFF or EWX_FORCE, 0);
end
else
MessageDlg('Soft Power Off not supported on this system.', mtWarning, [mbOK], 0);
end;
To lock the workstation, requiring the password if set is:
function LockWorkStation: boolean; stdcall; external 'user32.dll' name 'LockWorkStation';
procedure machine_lock;
begin
if not LockWorkStation then
MessageDlg('System not locked successfully.', mtWarning, [mbOK], 0);
end;
Standby
function SetSuspendState(hibernate, forcecritical, disablewakeevent: boolean): boolean; stdcall; external 'powrprof.dll' name 'SetSuspendState';
function IsHibernateAllowed: boolean; stdcall; external 'powrprof.dll' name 'IsPwrHibernateAllowed';
function IsPwrSuspendAllowed: Boolean; stdcall; external 'powrprof.dll' name 'IsPwrSuspendAllowed';
function IsPwrShutdownAllowed: Boolean; stdcall; external 'powrprof.dll' name 'IsPwrShutdownAllowed';
To put the system into standby mode, do this:
procedure machine_standby;
begin
if IsPwrSuspendAllowed then
SetSuspendState(false, false, false)
else
MessageDlg('System Standby not supported on this system.', mtWarning, [mbOK], 0);
end;
To put the system into hibernate, do this:
procedure machine_hibernate;
begin
if IsHibernateAllowed then
SetSuspendState(true, false, false)
else
MessageDlg('System Hibernate not supported on this system.', mtWarning, [mbOK], 0);
end;