如果是在WIN2000下不能软件关机,请检查CMOS中有关POWER MANAGMENT SETUP 中的 ACPI FUNCTION 是否设为允许.
如果NT/2k下关机还要取得的权限 procedure 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;
在window98下直接调用ExitWindows就可以了,但在Win2k下不同,下面的程序可以让你在两种系统都可以用 function IsWin9x: Boolean; var OsInfo: TOSVERSIONINFO; begin OsInfo.dwOSVersionInfoSize := sizeof(TOSVERSIONINFO); GetVersionEx(OsInfo); Result := (OsInfo.dwPlatformId = VER_PLATFORM_WIN32_WINDOWS); end;function SetShutdownPrivilege(Enable: Boolean): Boolean; var PrevPrivileges: TTokenPrivileges; Privileges: TTokenPrivileges; Token: THandle; dwRetLen: DWord; begin Result := False; OpenProcessToken(GetCurrentProcess, TOKEN_ADJUST_PRIVILEGES or TOKEN_QUERY, Token); Privileges.PrivilegeCount := 1; if LookupPrivilegeValue(nil, 'SeShutdownPrivilege', Privileges.Privileges[0].LUID) then begin if Enable then Privileges.Privileges[0].Attributes := SE_PRIVILEGE_ENABLED else Privileges.Privileges[0].Attributes := 0; dwRetLen := 0; Result := AdjustTokenPrivileges(Token, False, Privileges, SizeOf(PrevPrivileges), PrevPrivileges, dwRetLen); end; CloseHandle(Token); end;procedure Reboot; begin Application.Terminate; if IsWin9x then ExitWindowsEx(EWX_FORCE or EWX_REBOOT, 0) else begin SetShutdownPrivilege(True); ExitWindowsEx(EWX_FORCE or EWX_REBOOT, 0); SetShutdownPrivilege(False); end; end;procedure ShutDown; begin Application.Terminate; if IsWin9x then ExitWindowsEx(EWX_FORCE or EWX_SHUTDOWN, 0) else begin SetShutdownPrivilege(True); ExitWindowsEx(EWX_FORCE or EWX_SHUTDOWN, 0); SetShutdownPrivilege(False); end; end;
我是说启动关闭软件的函数,关闭只有close就可以了,但是启动呢?
大多数的机器在CMOS中可以设置机器定时开机的,你用程序直接修改不就可了。
其它关机方法: (2)SetSystemPowerState(False, True); //Forces the system down (3)SendMessage(Application.Handle,WM_SYSCOMMAND, SC_MONITORPOWER, 0/-1);//{turn monitor on/off} (4)stop Windows from displaying critical error messages ? var wOldErrorMode : Word; begin wOldErrorMode :=SetErrorMode(SEM_FAILCRITICALERRORS ); try //Error code here finally SetErrorMode( wOldErrorMode ); end; end;
ExitWindowsEx(EWX_SHUTDOWN, 0); //关机,但是,不关闭电源
ExitWindowsEx(EWX_REBOOT , 0); // 重启
ExitWindowsEx(EWX_FORCE , 0); //强制关机
ExitWindowsEx(EWX_POWEROFF, 0); //关机,并且关闭电源
ExitWindowsEx(EWX_FORCEIFHUNG , 0); //
ACPI FUNCTION 是否设为允许.
procedure 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;
function IsWin9x: Boolean;
var
OsInfo: TOSVERSIONINFO;
begin
OsInfo.dwOSVersionInfoSize := sizeof(TOSVERSIONINFO);
GetVersionEx(OsInfo);
Result := (OsInfo.dwPlatformId = VER_PLATFORM_WIN32_WINDOWS);
end;function SetShutdownPrivilege(Enable: Boolean): Boolean;
var
PrevPrivileges: TTokenPrivileges;
Privileges: TTokenPrivileges;
Token: THandle;
dwRetLen: DWord;
begin
Result := False;
OpenProcessToken(GetCurrentProcess, TOKEN_ADJUST_PRIVILEGES or TOKEN_QUERY, Token);
Privileges.PrivilegeCount := 1;
if LookupPrivilegeValue(nil, 'SeShutdownPrivilege', Privileges.Privileges[0].LUID) then
begin
if Enable then
Privileges.Privileges[0].Attributes := SE_PRIVILEGE_ENABLED
else
Privileges.Privileges[0].Attributes := 0;
dwRetLen := 0;
Result := AdjustTokenPrivileges(Token, False, Privileges, SizeOf(PrevPrivileges), PrevPrivileges, dwRetLen);
end;
CloseHandle(Token);
end;procedure Reboot;
begin
Application.Terminate;
if IsWin9x then
ExitWindowsEx(EWX_FORCE or EWX_REBOOT, 0)
else
begin
SetShutdownPrivilege(True);
ExitWindowsEx(EWX_FORCE or EWX_REBOOT, 0);
SetShutdownPrivilege(False);
end;
end;procedure ShutDown;
begin
Application.Terminate;
if IsWin9x then
ExitWindowsEx(EWX_FORCE or EWX_SHUTDOWN, 0)
else
begin
SetShutdownPrivilege(True);
ExitWindowsEx(EWX_FORCE or EWX_SHUTDOWN, 0);
SetShutdownPrivilege(False);
end;
end;
(2)SetSystemPowerState(False, True); //Forces the system down
(3)SendMessage(Application.Handle,WM_SYSCOMMAND, SC_MONITORPOWER, 0/-1);//{turn monitor on/off}
(4)stop Windows from displaying critical error messages ?
var
wOldErrorMode : Word;
begin
wOldErrorMode :=SetErrorMode(SEM_FAILCRITICALERRORS );
try
//Error code here
finally
SetErrorMode( wOldErrorMode );
end;
end;
需要另一个常驻内存的后台进程来定时启动你的程序,也就是要另外做一个程序