一个简单的关机程序,但是有时候却无法关闭,非要再按一下关闭电脑的按钮才行,不然就一直出现桌面的图片!为什么呢?各位多多指教了!
代码如下:function GetSysTypes: Boolean;
var
  Ver: TOSVersionInfo;
begin
  Result := False;
  Ver.dwOSVersionInfoSize := SizeOf(TOSVersionInfo);
  if GetVersionEx(Ver) then
    if Ver.dwPlatformId = VER_PLATFORM_WIN32_WINDOWS then
      Result := True
    else
      Result := False;
end;function SetPrivilege(sPrivilegeName: AnsiString; bEnable: Boolean): Boolean;
var
  TPPrev, TP: TTokenPrivileges;
  Token : THandle;
  dwRetLen : DWord;
begin
  Result := False;
  OpenProcessToken(GetCurrentProcess, TOKEN_ADJUST_PRIVILEGES or
                   TOKEN_QUERY, Token);
  TP.PrivilegeCount := 1;
  if LookupPrivilegeValue(nil,PAnsiChar(sPrivilegeName),TP.Privileges[0].LUID) then
  begin
    if bEnable then
      TP.Privileges[0].Attributes := SE_PRIVILEGE_ENABLED
    else
      TP.Privileges[0].Attributes := 0;
    dwRetLen := 0;
    Result := AdjustTokenPrivileges(Token, False, TP, SizeOf(TPPrev), TPPrev, dwRetLen);
  end;
  CloseHandle(Token);
end;procedure ExitWin32Sys(iFlags: Integer);
begin
  if GetSysTypes then
    ExitWindowsEx(iFlags,0)
  else
    if SetPrivilege('SeShutdownPrivilege',True) then
      if not ExitWindowsEx(iFlags,0) then
        SetPrivilege('SeShutdownPrivilege',False);
end;
procedure TForm1.Button1Click(Sender: TObject);
begin
     ExitWin32Sys(EWX_FORCE or EWX_POWEROFF);
end;

解决方案 »

  1.   

    试一下这个行不行:
    procedure ShutDownWindows;
    const SE_SHUTDOWN_NAME = 'SeShutdownPrivilege';
    var
      hToken: THandle;
      tpCur, tpOld: TTokenPrivileges;
      iZero: DWORD;
    begin
      iZero := 0;
      OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES or TOKEN_QUERY, hToken);
      LookupPrivilegeValue(nil, SE_SHUTDOWN_NAME, tpCur.Privileges[0].Luid);
      tpCur.PrivilegeCount := 1;
      tpCur.Privileges[0].Attributes := SE_PRIVILEGE_ENABLED;
      AdjustTokenPrivileges(hToken, False, tpCur, SizeOf(TTokenPrivileges), tpOld, iZero);
      ExitWindowsEx(EWX_FORCE or EWX_POWEROFF, 0);
    end;
      

  2.   

    关机的代码,我用的
    procedure shutdown;
    var EWX_SHUTDOWN,EWX_FORCE:integer;
        VerInfo: TOSVersionInfo;
        hToken: THANDLE;
        tkp: TOKEN_PRIVILEGES;
        Nothing: Cardinal;
    begin    
        EWX_SHUTDOWN:=1;
        EWX_FORCE:=4;
        VerInfo.dwOSVersionInfoSize := SizeOf(VerInfo);
        GetVersionEx(VerInfo);
        if VerInfo.dwPlatformId = VER_PLATFORM_WIN32_NT then 
        begin
          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, 0, nil, Nothing);
        end;
        ExitWindowsEx(EWX_FORCE + EWX_SHUTDOWN + EWX_POWEROFF, 0);
    end;
      

  3.   

    这类代码Google上N多的http://lysoft.7u7.net