如何在2000/XP下面用程序关机?(30分)

  • 主题发起人 主题发起人 REbNik
  • 开始时间 开始时间
R

REbNik

Unregistered / Unconfirmed
GUEST, unregistred user!
[blue]我用了这么一个函数:ExitWindowsEx,参数是EWX_FORCE,结果是系统注销了;我后来又换了
一个参数EWX_POWEROFF,可是一点反应都没有。真不知道怎么回事,我听说是要有一个SE_SHUTDOWN_NAME
的特权。是不是这个东西的原因?希望有知道这个方法的高手指点。又及:Delphi下的Windows API查
起来很费劲,有没有什么好一点的资料或者方法,能比较清楚的参考一下?[/blue]
 
procedure TtvAPIThing.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 CloseWin(CloseType:Byte = 1); //关机程序
const
EWX_FORCE=4; //关闭所有程序并以其他用户身份登录
EWX_LOGOFF=0; //重新启动计算机并切换到MS-DOS方式
EWX_REBOOT=2; //重新启动计算机
EWX_SHUTDOWN=1;//关闭计算机
begin
if GetisWind2K then AdjustToken();
case CloseType of
EWX_LOGOFF:ExitWindowsEx(EWX_FORCE or EWX_LOGOFF,0);
EWX_REBOOT:ExitWindowsEx(EWX_REBOOT,0);
else
ExitWindowsEx(EWX_FORCE or EWX_SHUTDOWN,0); //
end;
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;

function GetisWind2K:Boolean; //判断是否为Nt,2k
var ver:integer;//版本号  
major:integer;//主版本号
// minor:integer;//次版本号
begin
Result:=False;
ver:=getversion();//获得版本号
major:=ver and 255;//获得主版本号
// minor:=(ver and 255*256)div 256; //获得次版本号
if major>=5 then Result:=True;
end;
 
function ShutDown(uFlags: Cardinal):boolean;
const
ADJUST_PRIV = TOKEN_QUERY or TOKEN_ADJUST_PRIVILEGES;
SHTDWN_PRIV = 'SeShutdownPrivilege';
PRIV_SIZE = sizeOf(TTokenPrivileges);

var
Len: DWORD;
TokenPriv, Dummy: TTokenPrivileges;
Token: THandle;
Error:integer;
begin
error:=0;
// 设置特权
// Delphi2:
//if not OpenProcessToken(GetCurrentProcess(), ADJUST_PRIV, @Token) then
if not OpenProcessToken(GetCurrentProcess(), ADJUST_PRIV, Token) then
Error := Error or 4;
if not LookupPrivilegeValue(nil, SHTDWN_PRIV,TokenPriv.Privileges[0].Luid) then
Error := Error or 8;
TokenPriv.Privileges[0].Attributes := SE_PRIVILEGE_ENABLED;
TokenPriv.PrivilegeCount := 1; // One privilege to set
if not AdjustTokenPrivileges(Token, false, TokenPriv, PRIV_SIZE,Dummy, Len) then
Error:=Error or 16;
ExitWindowsEx(uFlags, 0);
Result := (Error=0);
end;




procedure TForm1.Button1Click(Sender: TObject);
begin
ShutDown(EWX_POWEROFF + EWX_FORCE);//
end;
 


我也想知道如何在delphi下快速查询api ...
 
procedure TForm1.Button1Click(Sender: TObject);
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;
begin
//Application.Terminate;
if IsWin9x then//9x系统的关机
ExitWindowsEx(EWX_FORCE or EWX_SHUTDOWN, 0)
else
begin//2000系统的关机
SetShutdownPrivilege(True);
ExitWindowsEx(EWX_FORCE or EWX_SHUTDOWN or EWX_POWEROFF, 0);
SetShutdownPrivilege(False);
end;
end;
 
后退
顶部