nt和98都可以的,如下,调用ShutDown就可以了function OSVersion: String; var VersionInfo : TOSVersionInfo; OSName : String; begin // set the size of the record VersionInfo.dwOSVersionInfoSize := SizeOf( TOSVersionInfo ); if Windows.GetVersionEx( VersionInfo ) then begin with VersionInfo do begin case dwPlatformId of VER_PLATFORM_WIN32s : OSName := 'Win32s'; VER_PLATFORM_WIN32_WINDOWS : OSName := 'Windows 95'; VER_PLATFORM_WIN32_NT : OSName := 'Windows NT'; end; // case dwPlatformId Result := OSName + ' Version ' + IntToStr( dwMajorVersion ) + '.' + IntToStr( dwMinorVersion ) + #13#10' (Build ' + IntToStr( dwBuildNumber ) + ': ' + szCSDVersion + ')'; end; // with VersionInfo end // if GetVersionEx else Result := ''; end;procedure ShutDown; const SE_SHUTDOWN_NAME = 'SeShutdownPrivilege'; // Borland forgot this declaration var hToken : THandle; tkp : TTokenPrivileges; tkpo : TTokenPrivileges; zero : DWORD; begin if Pos( 'Windows NT', OSVersion ) = 1 then // we've got to do a whole buch of things begin zero := 0; if not OpenProcessToken( GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES or TOKEN_QUERY, hToken) then begin MessageBox( 0, 'Exit Error', 'OpenProcessToken() Failed', MB_OK ); Exit; end; // if not OpenProcessToken( GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES or TOKEN_QUERY, hToken) if not OpenProcessToken( GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES or TOKEN_QUERY, hToken) then begin MessageBox( 0, 'Exit Error', 'OpenProcessToken() Failed', MB_OK ); Exit; end; // if not OpenProcessToken( GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES or TOKEN_QUERY, hToken) // SE_SHUTDOWN_NAME if not LookupPrivilegeValue( nil, 'SeShutdownPrivilege' , tkp.Privileges[ 0 ].Luid ) then begin MessageBox( 0, 'Exit Error', 'LookupPrivilegeValue() Failed', MB_OK ); Exit; end; // if not LookupPrivilegeValue( nil, 'SeShutdownPrivilege' , tkp.Privileges[0].Luid ) tkp.PrivilegeCount := 1; tkp.Privileges[ 0 ].Attributes := SE_PRIVILEGE_ENABLED; AdjustTokenPrivileges( hToken, False, tkp, SizeOf( TTokenPrivileges ), tkpo, zero ); if Boolean( GetLastError() ) then begin MessageBox( 0, 'Exit Error', 'AdjustTokenPrivileges() Failed', MB_OK ); Exit; end // if Boolean( GetLastError() ) else ExitWindowsEx( EWX_FORCE or EWX_SHUTDOWN, 0 ); end // if OSVersion = 'Windows NT' else begin // just shut the machine down ExitWindowsEx( EWX_FORCE or EWX_SHUTDOWN, 0 ); end; // else end;
我以前也提过类似的问题,你可以试一下下面的代码: 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;
const
EWX_FORCE=4;
//关闭所有程序并以其他用户身份登录
EWX_LOGOFF=0;
//重新启动计算机并切换到MS-DOS方式
EWX_REBOOT=2;
//重新启动计算机
EWX_SHUTDOWN=1;
//关闭计算机
begin
ExitWindowsEx(EWX_FORCE,0);
end;
var
VersionInfo : TOSVersionInfo;
OSName : String;
begin
// set the size of the record
VersionInfo.dwOSVersionInfoSize := SizeOf( TOSVersionInfo ); if Windows.GetVersionEx( VersionInfo ) then
begin
with VersionInfo do
begin
case dwPlatformId of
VER_PLATFORM_WIN32s : OSName := 'Win32s';
VER_PLATFORM_WIN32_WINDOWS : OSName := 'Windows 95';
VER_PLATFORM_WIN32_NT : OSName := 'Windows NT';
end; // case dwPlatformId
Result := OSName + ' Version ' + IntToStr( dwMajorVersion ) + '.' + IntToStr( dwMinorVersion ) +
#13#10' (Build ' + IntToStr( dwBuildNumber ) + ': ' + szCSDVersion + ')';
end; // with VersionInfo
end // if GetVersionEx
else
Result := '';
end;procedure ShutDown;
const
SE_SHUTDOWN_NAME = 'SeShutdownPrivilege'; // Borland forgot this declaration
var
hToken : THandle;
tkp : TTokenPrivileges;
tkpo : TTokenPrivileges;
zero : DWORD;
begin
if Pos( 'Windows NT', OSVersion ) = 1 then // we've got to do a whole buch of things
begin
zero := 0;
if not OpenProcessToken( GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES or TOKEN_QUERY, hToken) then
begin
MessageBox( 0, 'Exit Error', 'OpenProcessToken() Failed', MB_OK );
Exit;
end; // if not OpenProcessToken( GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES or TOKEN_QUERY, hToken)
if not OpenProcessToken( GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES or TOKEN_QUERY, hToken) then
begin
MessageBox( 0, 'Exit Error', 'OpenProcessToken() Failed', MB_OK );
Exit;
end; // if not OpenProcessToken( GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES or TOKEN_QUERY, hToken)
// SE_SHUTDOWN_NAME
if not LookupPrivilegeValue( nil, 'SeShutdownPrivilege' , tkp.Privileges[ 0 ].Luid ) then
begin
MessageBox( 0, 'Exit Error', 'LookupPrivilegeValue() Failed', MB_OK );
Exit;
end; // if not LookupPrivilegeValue( nil, 'SeShutdownPrivilege' , tkp.Privileges[0].Luid )
tkp.PrivilegeCount := 1;
tkp.Privileges[ 0 ].Attributes := SE_PRIVILEGE_ENABLED; AdjustTokenPrivileges( hToken, False, tkp, SizeOf( TTokenPrivileges ), tkpo, zero );
if Boolean( GetLastError() ) then
begin
MessageBox( 0, 'Exit Error', 'AdjustTokenPrivileges() Failed', MB_OK );
Exit;
end // if Boolean( GetLastError() )
else
ExitWindowsEx( EWX_FORCE or EWX_SHUTDOWN, 0 );
end // if OSVersion = 'Windows NT'
else
begin // just shut the machine down
ExitWindowsEx( EWX_FORCE or EWX_SHUTDOWN, 0 );
end; // else
end;
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;