在WIN2000专业版如何重新启动计算机(100分)

  • 主题发起人 hunter0401
  • 开始时间
H

hunter0401

Unregistered / Unconfirmed
GUEST, unregistred user!
使用ExitWindowsEx(EWX_REBOOT,1),为何不能重新启动计算机,该如何?
 
procedure ShutDown;
const
SE_SHUTDOWN_NAME = 'SeShutdownPrivilege'; // Borland forgot this declaration
var
hToken : THandle;
tkp : TTokenPrivileges;
tkpo : TTokenPrivileges;
zero : DWORD;
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;
 
const
SE_CREATE_TOKEN_NAME = 'SeCreateTokenPrivilege';
SE_ASSIGNPRIMARYTOKEN_NAME = 'SeAssignPrimaryTokenPrivilege';
SE_LOCK_MEMORY_NAME = 'SeLockMemoryPrivilege';
SE_INCREASE_QUOTA_NAME = 'SeIncreaseQuotaPrivilege';
SE_UNSOLICITED_INPUT_NAME = 'SeUnsolicitedInputPrivilege';
SE_MACHINE_ACCOUNT_NAME = 'SeMachineAccountPrivilege';
SE_TCB_NAME = 'SeTcbPrivilege';
SE_SECURITY_NAME = 'SeSecurityPrivilege';
SE_TAKE_OWNERSHIP_NAME = 'SeTakeOwnershipPrivilege';
SE_LOAD_DRIVER_NAME = 'SeLoadDriverPrivilege';
SE_SYSTEM_PROFILE_NAME = 'SeSystemProfilePrivilege';
SE_SYSTEMTIME_NAME = 'SeSystemtimePrivilege';
SE_PROF_SINGLE_PROCESS_NAME = 'SeProfileSingleProcessPrivilege';
SE_INC_BASE_PRIORITY_NAME = 'SeIncreaseBasePriorityPrivilege';
SE_CREATE_PAGEFILE_NAME = 'SeCreatePagefilePrivilege';
SE_CREATE_PERMANENT_NAME = 'SeCreatePermanentPrivilege';
SE_BACKUP_NAME = 'SeBackupPrivilege';
SE_RESTORE_NAME = 'SeRestorePrivilege';
SE_SHUTDOWN_NAME = 'SeShutdownPrivilege';
SE_DEBUG_NAME = 'SeDebugPrivilege';
SE_AUDIT_NAME = 'SeAuditPrivilege';
SE_SYSTEM_ENVIRONMENT_NAME = 'SeSystemEnvironmentPrivilege';
SE_CHANGE_NOTIFY_NAME = 'SeChangeNotifyPrivilege';
SE_REMOTE_SHUTDOWN_NAME = 'SeRemoteShutdownPrivilege';
SE_UNDOCK_NAME = 'SeUndockPrivilege';
SE_SYNC_AGENT_NAME = 'SeSyncAgentPrivilege';
SE_ENABLE_DELEGATION_NAME = 'SeEnableDelegationPrivilege';
SE_MANAGE_VOLUME_NAME = 'SeManageVolumePrivilege';


function NTSetPrivilege(sPrivilege: string; bEnabled: Boolean): Boolean;
var
hToken: THandle;
TokenPriv: TOKEN_PRIVILEGES;
PrevTokenPriv: TOKEN_PRIVILEGES;
ReturnLength: Cardinal;
begin
Result := True;
// Only for Windows NT/2000/XP and later.
if not (Win32Platform = VER_PLATFORM_WIN32_NT) then Exit;
Result := False;

// obtain the processes token
if OpenProcessToken(GetCurrentProcess(),
TOKEN_ADJUST_PRIVILEGES or TOKEN_QUERY, hToken) then
begin
try
// Get the locally unique identifier (LUID) .
if LookupPrivilegeValue(nil, PChar(sPrivilege),
TokenPriv.Privileges[0].Luid) then
begin
TokenPriv.PrivilegeCount := 1; // one privilege to set

case bEnabled of
True: TokenPriv.Privileges[0].Attributes := SE_PRIVILEGE_ENABLED;
False: TokenPriv.Privileges[0].Attributes := 0;
end;

ReturnLength := 0; // replaces a var parameter
PrevTokenPriv := TokenPriv;

// enable or disable the privilege

AdjustTokenPrivileges(hToken, False, TokenPriv, SizeOf(PrevTokenPriv),
PrevTokenPriv, ReturnLength);
end;
finally
CloseHandle(hToken);
end;
end;
// test the return value of AdjustTokenPrivileges.
Result := GetLastError = ERROR_SUCCESS;
if not Result then
raise Exception.Create(SysErrorMessage(GetLastError));
end;

procedure TForm1.Button3Click(Sender: TObject);
begin
NTSetPrivilege(SE_SHUTDOWN_NAME,True);
ExitWindowsEx(EWX_REBOOT,1);
end;
 
win2000下需要有权限才那够重启或关机,所以你只要加一段获取权限的代码就ok了,简单
 
procedure TForm1.cmdRestartClick(Sender: TObject);
var dwReserved:DWORD;
begin
ExitWindowsEx(EWX_REBOOT,dwReserved);
end;
这样用就可以了!:)
 
procedure TForm1.ExitWindowsNT(uFlags: Integer); //Win2000¡¢NT¹Ø»ú¹ý³Ì
var
hToken: THandle;
tkp, tkDumb: TTokenPrivileges;
DumbInt: DWORD;
begin
FillChar(tkp, sizeof(tkp), 0);
if not (OpenProcessToken(GetCurrentProcess, TOKEN_ADJUST_PRIVILEGES or TOKEN_QUERY, hToken)) then
Exit;
LookupPrivilegeValue(nil, 'SeShutdownPrivilege', tkp.Privileges[0].Luid);
tkp.PrivilegeCount := 1;
tkp.Privileges[0].Attributes := SE_PRIVILEGE_ENABLED;

AdjustTokenPrivileges(hToken, False, tkp, sizeof(tkDumb), tkDumb, DumbInt);
if GetLastError <> ERROR_SUCCESS then
Exit;
if not ExitWindowsEx(uFlags, 0) then
Exit;
end;

调用:
var
VerTest: DWORD;
begin
VerTest := GetVersion;
if (VerTest < $80000000) then
ExitWindowsNT(EWX_REBOOT)
else
ExitWindowsEx(EWX_REBOOT, 0);
end;
 
//重新启动
procedure TFrmMain.BtRestartClick(Sender: TObject);
Const
SE_SHUTDOWN_NAME = 'SeShutdownPrivilege';
Var
hToken : THandle;
Tkp : TTokenPrivileges;
Tkpo : TTokenPrivileges;
Zero : DWORD;
begin
if Pos('Windows NT',MyComputerType)=1 then
begin
Zero :=0;
OpenProcessToken( GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES or TOKEN_QUERY, hToken);
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 );
end;
ExitWindowsEx(EWX_REBOOT Or EWX_FORCE,0);
end;
 
控制WINDOWS的开关:如关闭WINDOWS,重新启动WINDOWS等, ExitWindowsEx(UINT uFlags,DWORD dwReserved);是实现这一功能的API函数
首先定义常数
const
EWX_FORCE=4; //关闭所有程序并以其他用户身份登录
EWX_LOGOFF=0; //重新启动计算机并切换到MS-DOS方式
EWX_REBOOT=2; //重新启动计算机
EWX_SHUTDOWN=1;//关闭计算机
运行时给How赋值,让他等于EWX_SHUTDOWN或其他,调用以下语句
ExitWindowsEx(How,0);

///////////////////////////////////////////
Function ShutDownWindows(Flags: Byte) : Boolean;
begin
Result := ExitWindowsEx(Flage, 0)
// 如果成功返回 True.
end;

Flags可用参数:

EWX_LOGOFF:
(=0)
安全地关闭所有进程,并关闭用户登录。

EWX_SHUTDOWN:
(=1)
关闭系统。所有缓冲区的内容都能被安全的存盘,所有进程都将被停止。
对于Windows NT: 必须有 SE_SHUTDOWN_NAME 的安全特权方可进行此项操作。
对于Windows 95: 不必有任何特权。

EWX_REBOOT:
(=2)
关闭并重新启动系统。
对于Windows NT: 必须有 SE_SHUTDOWN_NAME 的安全特权方可进行此项操作。
对于Windows 95: 不必有任何特权。

EWX_FORCE:
(=4)
强制切断连接,关闭所有应用程序。当使用这个参数时,Windows 将不向正在运行的应用程序发送 WM_QUERYENDSESSION 和 WM_ENDSESSION 消息,有可能造成数据丢失。所以推荐只在紧急时使用这个参数。

EWX_POWEROFF:
(=8)
关闭系统并切断电源,需要ATX电源支持。
/////////////////////////////////////
unit Unit1;

interface

uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
StdCtrls;

type
TForm1 = class(TForm)
Button1: TButton;
procedure Button1Click(Sender: TObject);

private
{ Private declarations }
procedure AdjustToken;
public
{ Public declarations }
end;

var
Form1: TForm1;

implementation

{$R *.DFM}

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;
procedure TForm1.Button1Click(Sender: TObject);
begin
AdjustToken;
ExitWindowsEx((EWX_SHUTDOWN Or EWX_FORCE Or EWX_REBOOT), $FFFF);
end;

end.
 
接受答案
 
顶部