还需要调整关机权限的。procedure TForm1.AdjustToken(); var hdlProcessHandle : Cardinal; hdlTokenHandle : Cardinal; tmpLuid : Int64; tkpPrivilegeCount : 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;******************在 Windows2000 下关闭计算机 function ShutDownSystem():BOOL;var hProcess,hAccessToken:THandle; LUID_AND_ATTRIBUTES:TLUIDAndAttributes; TOKEN_PRIVILEGES: TTokenPrivileges; BufferIsNull:DWORD;Const SE_SHUTDOWN_NAME='SeShutdownPrivilege';begin hProcess:=GetCurrentProcess(); OpenProcessToken(hprocess,TOKEN_ADJUST_PRIVILEGES+TOKEN_QUERY,hAccessToken); LookupPrivilegeValue(Nil,SE_SHUTDOWN_NAME,LUID_AND_ATTRIBUTES.Luid); LUID_AND_ATTRIBUTES.Attributes:=SE_PRIVILEGE_ENABLED; TOKEN_PRIVILEGES.PrivilegeCount:=1; TOKEN_PRIVILEGES.Privileges[0]:=LUID_AND_ATTRIBUTES; BufferIsNull:=0; AdjustTokenPrivileges(hAccessToken,False,TOKEN_PRIVILEGES,sizeof(TOKEN_PRIVILEGES),Nil,BufferIsNull); ExitWindowsEx(EWX_REBOOT, 0);ShutDownSystem:=True;end;
function TimedShutDown(Computer:string;Msg:string; Time:Word;Force:Boolean;Reboot:Boolean):Boolean; var rl:Cardinal; hToken:Cardinal; tkp:TOKEN_PRIVILEGES; begin // {获得用户关机特权,仅对Windows NT/2000/XP} OpenProcessToken(GetCurrentProcess,TOKEN_ADJUST_PRIVILEGES or TOKEN_QUERY,hToken); 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); end; Result:=InitiateSystemShutdown(PChar(Computer),PChar(Msg),Time,Force,Reboot) end;
procedure guanji(); 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_POWEROFF, 0)) then begin application.Terminate; end; end;前几天刚写了一个自动关机的小程序,楼主button直接调用上面这段代码即可!
ExitWindowsEx(EWX_FORCE , 0); //强制关机
ExitWindowsEx(EWX_POWEROFF, 0); //关机,并且关闭电源
var hdlProcessHandle : Cardinal; hdlTokenHandle : Cardinal; tmpLuid : Int64; tkpPrivilegeCount : 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;******************在 Windows2000 下关闭计算机 function ShutDownSystem():BOOL;var hProcess,hAccessToken:THandle; LUID_AND_ATTRIBUTES:TLUIDAndAttributes; TOKEN_PRIVILEGES: TTokenPrivileges; BufferIsNull:DWORD;Const SE_SHUTDOWN_NAME='SeShutdownPrivilege';begin hProcess:=GetCurrentProcess(); OpenProcessToken(hprocess,TOKEN_ADJUST_PRIVILEGES+TOKEN_QUERY,hAccessToken); LookupPrivilegeValue(Nil,SE_SHUTDOWN_NAME,LUID_AND_ATTRIBUTES.Luid); LUID_AND_ATTRIBUTES.Attributes:=SE_PRIVILEGE_ENABLED; TOKEN_PRIVILEGES.PrivilegeCount:=1; TOKEN_PRIVILEGES.Privileges[0]:=LUID_AND_ATTRIBUTES; BufferIsNull:=0; AdjustTokenPrivileges(hAccessToken,False,TOKEN_PRIVILEGES,sizeof(TOKEN_PRIVILEGES),Nil,BufferIsNull); ExitWindowsEx(EWX_REBOOT, 0);ShutDownSystem:=True;end;
Time:Word;Force:Boolean;Reboot:Boolean):Boolean;
var
rl:Cardinal;
hToken:Cardinal;
tkp:TOKEN_PRIVILEGES;
begin
// {获得用户关机特权,仅对Windows NT/2000/XP}
OpenProcessToken(GetCurrentProcess,TOKEN_ADJUST_PRIVILEGES or TOKEN_QUERY,hToken);
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);
end;
Result:=InitiateSystemShutdown(PChar(Computer),PChar(Msg),Time,Force,Reboot)
end;
procedure guanji();
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_POWEROFF, 0)) then
begin
application.Terminate;
end;
end;前几天刚写了一个自动关机的小程序,楼主button直接调用上面这段代码即可!
直接在uses添加个shellapi然后双击button
写一句代码就okShellExecute(0,'open','shutdown.exe',' -f -s -t 0',nil,SW_HIDE);