在nt系列中关机等编程要比9x系列麻烦很多。关键是要为当前进程获取关机权限。 下面的代码是我以前写着玩的,命令行关机:program ExitWin;{$APPTYPE CONSOLE}uses Windows;const SE_SHUTDOWN_NAME='SeShutdownPrivilege'; SE_PRIVILEGE_ENABLED=$00000002;var strOpt: string;function UpperCase(const S: string): string; var Ch: Char; L: Integer; Source, Dest: PChar; begin L := Length(S); SetLength(Result, L); Source := Pointer(S); Dest := Pointer(Result); while L <> 0 do begin Ch := Source^; if (Ch >= 'a') and (Ch <= 'z') then Dec(Ch, 32); Dest^ := Ch; Inc(Source); Inc(Dest); Dec(L); end; end;procedure PrintUsage; begin writeln('Usage: '); writeln('ExitWin [/reboot|/logoff|poweroff|/help|/?] '); writeln('No parameter means reboot. '); end;procedure ShutDown; var hToken: Thandle; tkp: TTokenPrivileges; fo, todo: DWORD; begin // Get a token for this process. OpenProcessToken( GetCurrentProcess(), (TOKEN_ADJUST_PRIVILEGES or TOKEN_QUERY), hToken ); // Get the LUID for the shutdown privilege. LookupPrivilegeValue( nil, pchar(SE_SHUTDOWN_NAME), tkp.Privileges[0].Luid ); // Prepare to set shutdown privilege. tkp.PrivilegeCount := 1; // one privilege to set tkp.Privileges[0].Attributes := SE_PRIVILEGE_ENABLED; // Get the shutdown privilege for this process. fo:=0; AdjustTokenPrivileges(hToken, false, tkp, 0, nil, fo); if (GetLastError() <> ERROR_SUCCESS) then writeln('Fail: AdjustTokenPrivileges'); // Shut down the system and force all applications to close. todo:=EWX_POWEROFF; if strOpt='/REBOOT' then todo:=EWX_REBOOT; if strOpt='/LOGOFF' then todo:=EWX_LOGOFF; if strOpt='/POWEROFF' then todo:=EWX_POWEROFF; if not(ExitWindowsEx(todo or EWX_FORCE, 0)) then writeln('Fail: ExitWindowsEx'); end;begin case ParamCount of 0: Shutdown; // case 0 , no parameter 1: begin // case 1 parameter strOpt:=UpperCase(ParamStr(1)); if strOpt='/HELP' then strOpt:='/?'; if strOpt='/?' then PrintUsage else ShutDown; end; // case 1 else PrintUsage; // case else , too many parameters end; end.
下面的代码是我以前写着玩的,命令行关机:program ExitWin;{$APPTYPE CONSOLE}uses
Windows;const
SE_SHUTDOWN_NAME='SeShutdownPrivilege';
SE_PRIVILEGE_ENABLED=$00000002;var
strOpt: string;function UpperCase(const S: string): string;
var
Ch: Char;
L: Integer;
Source, Dest: PChar;
begin
L := Length(S);
SetLength(Result, L);
Source := Pointer(S);
Dest := Pointer(Result);
while L <> 0 do
begin
Ch := Source^;
if (Ch >= 'a') and (Ch <= 'z') then Dec(Ch, 32);
Dest^ := Ch;
Inc(Source);
Inc(Dest);
Dec(L);
end;
end;procedure PrintUsage;
begin
writeln('Usage: ');
writeln('ExitWin [/reboot|/logoff|poweroff|/help|/?] ');
writeln('No parameter means reboot. ');
end;procedure ShutDown;
var
hToken: Thandle;
tkp: TTokenPrivileges;
fo, todo: DWORD;
begin // Get a token for this process.
OpenProcessToken(
GetCurrentProcess(),
(TOKEN_ADJUST_PRIVILEGES or TOKEN_QUERY),
hToken
); // Get the LUID for the shutdown privilege.
LookupPrivilegeValue(
nil,
pchar(SE_SHUTDOWN_NAME),
tkp.Privileges[0].Luid
); // Prepare to set shutdown privilege.
tkp.PrivilegeCount := 1; // one privilege to set
tkp.Privileges[0].Attributes := SE_PRIVILEGE_ENABLED; // Get the shutdown privilege for this process.
fo:=0;
AdjustTokenPrivileges(hToken, false, tkp, 0, nil, fo); if (GetLastError() <> ERROR_SUCCESS) then
writeln('Fail: AdjustTokenPrivileges'); // Shut down the system and force all applications to close.
todo:=EWX_POWEROFF;
if strOpt='/REBOOT' then todo:=EWX_REBOOT;
if strOpt='/LOGOFF' then todo:=EWX_LOGOFF;
if strOpt='/POWEROFF' then todo:=EWX_POWEROFF; if not(ExitWindowsEx(todo or EWX_FORCE, 0)) then
writeln('Fail: ExitWindowsEx');
end;begin
case ParamCount of
0: Shutdown; // case 0 , no parameter
1: begin // case 1 parameter
strOpt:=UpperCase(ParamStr(1));
if strOpt='/HELP' then strOpt:='/?';
if strOpt='/?'
then PrintUsage
else ShutDown;
end; // case 1
else PrintUsage; // case else , too many parameters
end;
end.