环境:机子的操作系统是Win2000,取消了登陆时必须输入用户名和密码,
问题:
我写了个自动关机的垃圾,关机调用的是windows的API函数ExitWindows(),我是要关机,所以用的参数是ExitWindows(8,0),但是运行之后只是注销了,并没有关机,
然后我考虑使用ExitWindowsEx(8,0),结果没有任何反应,我把参数改为ExitWindowsEx((EWX_POWEROFF or EWX_FORCE),0),运行之后系统没有任何反应,
请问是我调用API的方式不对,还是参数设置错误,或者是系统设置问题
ps:我在MSDN查这个函数,这些参数都支持Window2000及以后的系统,本人非常费解,谢谢。。

解决方案 »

  1.   

    有两种
    No.1:  CO = (ocReboot,ocShutdown,ocForce_Shutdown,ocLogoff);
      {重启,关机,强行关机,注销}function ComputerOPtion(i:CO):boolean;
    var
      hToken :THandle;
      tkp : TOKEN_PRIVILEGES;
      ReturnLength : DWord;
    begin
      RESULT:=false;
      if (not OpenProcessToken(GetCurrentProcess(),TOKEN_ADJUST_PRIVILEGES or TOKEN_ALL_ACCESS or TOKEN_QUERY, hToken))
      then
        RESULT:=false;
        LookupPrivilegeValue(nil,'SeShutdownPrivilege',tkp.Privileges[0].Luid);
        tkp.PrivilegeCount := 1;
        tkp.Privileges[0].Attributes :=SE_PRIVILEGE_ENABLED;
        ReturnLength :=0;
        AdjustTokenPrivileges(hToken, FALSE, tkp, 0,nil,ReturnLength);    if (GetLastError() <> ERROR_SUCCESS) then
        RESULT:=false;
       case i of
        ocReboot: begin
          ExitWindowsEx(EWX_REBOOT, 0); //reboot
          RESULT:=true;
        end;
        ocShutdown:begin
            ExitWindowsEx(EWX_SHUTDOWN, 0); //shutdown
            RESULT:=true;
          end;
        ocForce_Shutdown: begin
            ExitWindowsEx(EWX_FORCE+EWX_SHUTDOWN, 0); //force shutdown
            RESULT:=true;
          end;
        ocLogoff: begin
            ExitWindowsEx(EWX_LOGOFF, 0); //logoff
            RESULT:=true;
          end;
       end;
    end;No.2: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 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_PRIVILEGES),Nil,BufferIsNull);
      ExitWindowsEx(EWX_REBOOT, 0);
      ShutDownSystem:=True;
    end;
    {}
      vStr := Trim(C_Socket.Socket.ReceiveText);
      if CompareText(LeftStr(vStr,12),'CloseWindows') = 0 then
      begin
        if CompareText(LeftStr(GetWindowsVer,1),'9') = 0 then
        begin
          ExitWindowsEx(EWX_SHUTDOWN or EWX_FORCE,0);
        end else
           if ShutDownSystem then
              ExitWindowsEx(EWX_SHUTDOWN or EWX_FORCE,0);{我选取了我程序中的一部分代码}
    2000可以的,XP也可以的。
      

  2.   

    权限问题,你需要SeShutdownPrivilege才可以操作
    上面就是方法了