delphi, 在 windows2000下,如何编写“强制关机”程序?(50分)

  • 主题发起人 主题发起人 geoffrey
  • 开始时间 开始时间
G

geoffrey

Unregistered / Unconfirmed
GUEST, unregistred user!
下面是我的代码,
发现ewx_poweroff和ewx_logoff效果是一样的,ewx_shutdown根本不执行。


procedure TForm1.ToolButton1Click(Sender: TObject);
begin
case radiogroup1.ItemIndex of
0: begin
if win32platform =ver_platform_win32_windows then
exitwindowsex(ewx_force+ewx_shutdown+ewx_poweroff,32);
if win32platform =ver_platform_win32_NT then
operatecomputer(ewx_poweroff); //ewx_logoff Ϊ¹Ø»ú
end;
1: begin
if win32platform =ver_platform_win32_windows then
exitwindowsex(ewx_force+ewx_shutdown+ewx_poweroff,32);
if win32platform =ver_platform_win32_NT then
operatecomputer(ewx_reboot); //ewx_reboot ΪÖØÆô
end;
2: begin
if win32platform =ver_platform_win32_windows then
exitwindowsex(ewx_force+ewx_shutdown+ewx_poweroff,32);
if win32platform =ver_platform_win32_NT then
operatecomputer(ewx_logoff); //ewx_logoff ΪעÏú
end;
end;
end;

procedure operatecomputer(statue:longword);
var
hToken:THandle;
tkp : TOKEN_PRIVILEGES;
ReturnLength : DWord;
begin
if (not OpenProcessToken(GetCurrentProcess(),TOKEN_ADJUST_PRIVILEGES or TOKEN_ALL_ACCESS or TOKEN_QUERY, hToken))then
begin
application.Terminate;
end;
LookupPrivilegeValue(nil,'SeShutdownPrivilege',tkp.Privileges[0].Luid);
tkp.PrivilegeCount := 1;
tkp.Privileges[0].Attributes :=SE_PRIVILEGE_ENABLED;
ReturnLength :=0;
AdjustTokenPrivileges(hToken, FALSE, tkp, 0,nil,ReturnLength);
if (GetLastError() <> ERROR_SUCCESS) then
begin
application.Terminate;
end;
if (not ExitWindowsEx(statue, 0)) then
begin
application.Terminate;
end;
end;
 
ExitWindowsEx(EWX_LOGOFF , 0); //注销
ExitWindowsEx(EWX_SHUTDOWN, 0); //关机,但是,不关闭电源
ExitWindowsEx(EWX_REBOOT , 0); // 重启
ExitWindowsEx(EWX_FORCE , 0); //强制关机
ExitWindowsEx(EWX_POWEROFF, 0); //关机,并且关闭电源
ExitWindowsEx(EWX_FORCEIFHUNG , 0); //



这个我自己测试通过的
private
{ Private declarations }
procedure AdjustToken; // 在private里面添加

然后定义
procedure TForm1.AdjustToken;
var
hdlProcessHandle : Cardinal;
hdlTokenHandle : Cardinal;
tmpLuid : Int64;
tkp : TOKEN_PRIVILEGES;
tkpNewButIgnored : TOKEN_PRIVILEGES;
lBufferNeeded : Cardinal;
Privilege : array[0..0] of _LUID_AND_ATTRIBUTES;
begin
hdlProcessHandle := GetCurrentProcess;
OpenProcessToken(hdlProcessHandle,
(TOKEN_ADJUST_PRIVILEGES Or TOKEN_QUERY),
hdlTokenHandle);
// Get the LUID for shutdown privilege.
LookupPrivilegeValue('', 'SeShutdownPrivilege', tmpLuid);
Privilege[0].Luid := tmpLuid;
Privilege[0].Attributes := SE_PRIVILEGE_ENABLED;
tkp.PrivilegeCount := 1; // One privilege to set
tkp.Privileges[0] := Privilege[0];
// Enable the shutdown privilege in the access token of this process.
AdjustTokenPrivileges(hdlTokenHandle,False,tkp,Sizeof(tkpNewButIgnored),
tkpNewButIgnored,lBufferNeeded);
end;


最后调用

procedure TForm1.Button2Click(Sender: TObject);
begin
AdjustToken;
exitwindowsex(EWX_FORCE + EWX_SHUTDOWN ,0);
end;
以上适用于 2k和xp,我都测试过
 
//Windows NT下重启过程
procedure ReBootWinNT;
var
currToken : THandle;
prevState,
newState : TTokenPrivileges;
prevStateLen : DWORD;
uid : TLargeInteger;
begin
// Set the privledges so we CAN reboot...
OpenProcessToken(GetCurrentProcess, TOKEN_ADJUST_PRIVILEGES or TOKEN_QUERY, currToken);
LookupPrivilegeValue(nil, 'SeShutdownPrivilege', uid);
newState.PrivilegeCount := 1;
newState.Privileges[0].Attributes := SE_PRIVILEGE_ENABLED;
newState.Privileges[0].Luid := uid;

AdjustTokenPrivileges(currToken, False, newState, sizeof(TTokenPrivileges), prevState, prevStateLen);
// Go ahead and reboot...
ExitWindowsEX(EWX_REBOOT OR EWX_FORCE, 0);
end;

//Windows NT下关机过程
procedure ShutDownWinNT;
var
hToken:THandle;
tkp : TOKEN_PRIVILEGES;
ReturnLength : DWord;
begin
if (not OpenProcessToken(GetCurrentProcess(),TOKEN_ADJUST_PRIVILEGES or TOKEN_ALL_ACCESS or TOKEN_QUERY, hToken))then
begin
application.Terminate;
end;
LookupPrivilegeValue(nil,'SeShutdownPrivilege',tkp.Privileges[0].Luid);
tkp.PrivilegeCount := 1;
tkp.Privileges[0].Attributes :=SE_PRIVILEGE_ENABLED;
ReturnLength :=0;
AdjustTokenPrivileges(hToken, FALSE, tkp, 0,nil,ReturnLength);
if (GetLastError() <> ERROR_SUCCESS) then
begin
application.Terminate;
end;

if (not ExitWindowsEx(EWX_SHUTDOWN or EWX_FORCE or EWX_POWEROFF , 0)) then
begin
application.Terminate;
end;
end;
2k和xp都能用
 
后退
顶部