在win2000系统中用Delphi6运得API函数ExitWindowsEx(exw_shutdow, 0);但不成功。上网查找说要系统支持power-off 特性。请问什么是Power-off特性?怎样实现?谢谢!

解决方案 »

  1.   

    2000,xp下关机要权限的~~
    procedure TForm1.shutdown;
    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;
      OSVersionInfo: TOSVERSIONINFO;
      result: boolean;
    begin
      OSVersionInfo.dwOSVersionInfoSize := sizeof(OSVERSIONINFO);
      GetVersionEx(OSVersionInfo);
      // 如果是Win NT/2000操作系统
      if (OSVersionInfo.dwPlatformId = VER_PLATFORM_WIN32_NT) then
      begin
        error:=0;
        // 设置特权
        //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(EWX_POWEROFF or EWX_FORCE, 0);
        Result:= (Error=0);
      end
      else
        ExitWindowsEx(ewx_force or ewx_shutdown or ewx_poweroff,0);
    end; {ShutDown}
      

  2.   

    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;
            Privil
    ege[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;
    ******************
    在Windows2000下关闭计算机
    function ShutDownSystem():BOOL;
    var
      hProcess,hAccessToken:THandle;
      LUID_AND_ATTRIBUTES:TLUIDAndAttributes;
      TOKEN_PRIVILEGES: TTokenPrivileges;
      BufferIsNull:DWORD;
    Const
      SE_SHUTDOWN_NAME='SeShutdownPrivilege';
    begin
      hProcess:=GetCurrentProcess();OpenProcessToken(hprocess,TOKEN_ADJUST_PRIVILEGES+TOKEN_QUERY,hAccessToken);
      LookupPrivilegeValue(Nil,SE_SHUTDOWN_NAME,LUID_AND_ATTRIBUTES.Luid);
      LUID_AND_ATTRIBUTES.Attributes:=SE_PRIVILEGE_ENABLED;
      TOKEN_PRIVILEGES.PrivilegeCount:=1;
      TOKEN_PRIVILEGES.Privileges[0]:=LUID_AND_ATTRIBUTES;
      BufferIsNull:=0;AdjustTokenPrivileges(hAccessToken,False,TOKEN_PRIVILEGES,sizeof(TOKEN_PRIVI
    LEGES),Nil,BufferIsNull);
      ExitWindowsEx(EWX_REBOOT, 0);
    ShutDownSystem:=True;
    end;
      

  3.   

    /////////////////////////////////////////////
    function ShutDownSystem:boolean; //关闭2K系统;
    var
    hProcess,hAccessToken:THandle;
    LUID_AND_ATTRIBUTES:TLUIDAndAttributes;
    TOKEN_PRIVILEGES: TTokenPrivileges;
    BufferIsNull:DWORD;
    Const
    SE_SHUTDOWN_NAME='SeShutdownPrivilege';
    begin
      hProcess:=GetCurrentProcess();
      OpenProcessToken(hprocess,TOKEN_ADJUST_PRIVILEGES+TOKEN_QUERY,hAccessToken);
      LookupPrivilegeValue(Nil,SE_SHUTDOWN_NAME,LUID_AND_ATTRIBUTES.Luid);
      LUID_AND_ATTRIBUTES.Attributes:=SE_PRIVILEGE_ENABLED;
      TOKEN_PRIVILEGES.PrivilegeCount:=1;
      TOKEN_PRIVILEGES.Privileges[0]:=LUID_AND_ATTRIBUTES;
      BufferIsNull:=0;
      AdjustTokenPrivileges(hAccessToken,False,TOKEN_PRIVILEGES,sizeof(TOKEN_PRIVILEGES),Nil,BufferIsNull);
      ExitWindowsEx(EWX_POWEROFF, 0);
      ShutDownSystem:=True;
    end;
    //////////////////////////////////////////////////////
    function ReBootSystem:boolean; //重启2K系统;
    var
    hProcess,hAccessToken:THandle;
    LUID_AND_ATTRIBUTES:TLUIDAndAttributes;
    TOKEN_PRIVILEGES: TTokenPrivileges;
    BufferIsNull:DWORD;
    Const
    SE_SHUTDOWN_NAME='SeShutdownPrivilege';
    begin
      hProcess:=GetCurrentProcess();
      OpenProcessToken(hprocess,TOKEN_ADJUST_PRIVILEGES+TOKEN_QUERY,hAccessToken);
      LookupPrivilegeValue(Nil,SE_SHUTDOWN_NAME,LUID_AND_ATTRIBUTES.Luid);
      LUID_AND_ATTRIBUTES.Attributes:=SE_PRIVILEGE_ENABLED;
      TOKEN_PRIVILEGES.PrivilegeCount:=1;
      TOKEN_PRIVILEGES.Privileges[0]:=LUID_AND_ATTRIBUTES;
      BufferIsNull:=0;
      AdjustTokenPrivileges(hAccessToken,False,TOKEN_PRIVILEGES,sizeof(TOKEN_PRIVILEGES),Nil,BufferIsNull);
      ExitWindowsEx(EWX_ReBoot, 0);
      ReBootSystem:=True;
    end;
    ////////////////////////////////////////////////////
    //关机方法之2///////////////////////////////////////
    function ShutMeDown:string;
    var
      hToken : THandle;
      tkp,p  : TTokenPrivileges;
      RetLen : DWord;
      ExReply: LongBool;
      Reply  : DWord;
    begin
      case Win32Platform of
           VER_PLATFORM_WIN32_WINDOWS: //***Windows 9x/ME***//
                  begin
                    ExReply:= ExitWindowsEx(EWX_POWEROFF or EWX_SHUTDOWN or EWX_FORCE,0);
                    if ExReply then
                     Result:='Shutdown Initiated'
                    else
                    Result:='Shutdown failed with ' + IntToStr(GetLastError);
                  end;
           VER_PLATFORM_WIN32_NT:  //***Windows NT/2000/XP***//
                  begin
                   if OpenProcessToken(GetCurrentProcess,TOKEN_ADJUST_PRIVILEGES or TOKEN_QUERY,hToken) then
                     begin
                          if LookupPrivilegeValue(nil,'SeShutdownPrivilege',tkp.Privileges[0].Luid) then
                           begin
                               tkp.PrivilegeCount := 1;
                               tkp.Privileges[0].Attributes :=SE_PRIVILEGE_ENABLED;
                               AdjustTokenPrivileges(hToken,False,tkp,SizeOf(TTokenPrivileges),p,RetLen);
                               Reply := GetLastError;
                               if Reply = ERROR_SUCCESS then
                                  begin
                                    ExReply:= ExitWindowsEx(ewx_shutdown or EWX_POWEROFF, 0);
                                    if ExReply then
                                    Result:='Shutdown Initiated'
                                    else
                                    Result:='Shutdown failed with ' + IntToStr(GetLastError);
                                  end;
                            end;
                     end;
                   end;
       end; //end case
    end;
    ////////////////////////////////////////////////////
    /////////////重启方法2//////////////////////////////
     function ReBootSystem2:string;
    var
      hToken : THandle;
      tkp,p  : TTokenPrivileges;
      RetLen : DWord;
      ExReply: LongBool;
      Reply  : DWord;
    begin
      case Win32Platform of
           VER_PLATFORM_WIN32_WINDOWS: //***Windows 9x/ME***//
                  begin
                    ExReply:= ExitWindowsEx(EWX_REBOOT,0);
                    if ExReply then
                     Result:='Shutdown Initiated'
                    else
                    Result:='Shutdown failed with ' + IntToStr(GetLastError);
                  end;
           VER_PLATFORM_WIN32_NT:  //***Windows NT/2000/XP***//
                  begin
                   if OpenProcessToken(GetCurrentProcess,TOKEN_ADJUST_PRIVILEGES or TOKEN_QUERY,hToken) then
                     begin
                          if LookupPrivilegeValue(nil,'SeShutdownPrivilege',tkp.Privileges[0].Luid) then
                           begin
                               tkp.PrivilegeCount := 1;
                               tkp.Privileges[0].Attributes :=SE_PRIVILEGE_ENABLED;
                               AdjustTokenPrivileges(hToken,False,tkp,SizeOf(TTokenPrivileges),p,RetLen);
                               Reply := GetLastError;
                               if Reply = ERROR_SUCCESS then
                                  begin
                                    ExReply:= ExitWindowsEx(EWX_REBOOT, 0);
                                    if ExReply then
                                    Result:='Shutdown Initiated'
                                    else
                                    Result:='Shutdown failed with ' + IntToStr(GetLastError);
                                  end;
                            end;
                     end;
                   end;
       end; //end case
    end;
    ////////////////////////////////////////////////////