自动关机,在delphi里面可以做出来么?怎么做?能用代码写出来给小弟看么?

解决方案 »

  1.   

    可以用API实现,所以和开发工具无关!function ShutDownSystem: Boolean; 
    var
      VerInfo: TOSVersionInfo;
      hToken: THANDLE;
      tkp: TOKEN_PRIVILEGES;
      Nothing: Cardinal;
    begin
      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);
      Result:=True;
    end;98下
    ExitWindowsEx(EWX_FORCE + EWX_SHUTDOWN + EWX_POWEROFF, 0);
    就可以了,前面的代码用于在NT内核中获得足够权限!
      

  2.   

    function ShutDown(Action: integer): boolean;
    //Designed by  CK at xiamen, china;
    const
      ADJUST_PRIV = TOKEN_QUERY or TOKEN_ADJUST_PRIVILEGES;
      SHTDWN_PRIV = 'SeShutdownPrivilege';
      PRIV_SIZE = sizeOf(TTokenPrivileges);
    var
      uFlags: Cardinal;
      Len: DWORD;
      TokenPriv, Dummy: TTokenPrivileges;
      Token: THandle;
      Error: integer;
    begin
      error := 0;
      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;
      case Action of
        1: uFlags := EWX_POWEROFF + EWX_SHUTDOWN; //提示关机;
        2: uFlags := EWX_POWEROFF + EWX_FORCE; //强制关机
        3: uFlags := EWX_ReBoot; //提示重启系统
        4: uFlags := EWX_ReBoot + EWX_FORCE; //强制重启系统
      end;
      ExitWindowsEx(uFlags, 0);
      Result := (Error = 0);
    end;
      

  3.   

    控制WINDOWS的开关:如关闭WINDOWS,重新启动WINDOWS等, ExitWindowsEx(UINT uFlags,DWORD dwReserved);是实现这一功能的API函数
    首先定义常数
    const
    EWX_FORCE=4; //关闭所有程序并以其他用户身份登录
    EWX_LOGOFF=0; //重新启动计算机并切换到MS-DOS方式
    EWX_REBOOT=2; //重新启动计算机
    EWX_SHUTDOWN=1;//关闭计算机
    运行时给How赋值,让他等于EWX_SHUTDOWN或其他,调用以下语句
    ExitWindowsEx(How,0);///////////////////////////////////////////
    Function ShutDownWindows(Flags: Byte) : Boolean;
    begin
         Result := ExitWindowsEx(Flage, 0)
         // 如果成功返回 True.
    end;Flags可用参数:EWX_LOGOFF:
      (=0)
      安全地关闭所有进程,并关闭用户登录。EWX_SHUTDOWN:
      (=1)
      关闭系统。所有缓冲区的内容都能被安全的存盘,所有进程都将被停止。
      对于Windows NT: 必须有 SE_SHUTDOWN_NAME 的安全特权方可进行此项操作。
      对于Windows 95: 不必有任何特权。EWX_REBOOT:
      (=2)
      关闭并重新启动系统。
      对于Windows NT: 必须有 SE_SHUTDOWN_NAME 的安全特权方可进行此项操作。
      对于Windows 95: 不必有任何特权。EWX_FORCE:
      (=4)
       强制切断连接,关闭所有应用程序。当使用这个参数时,Windows 将不向正在运行的应用程序发送 WM_QUERYENDSESSION 和 WM_ENDSESSION 消息,有可能造成数据丢失。所以推荐只在紧急时使用这个参数。EWX_POWEROFF:
      (=8)
      关闭系统并切断电源,需要ATX电源支持。
    /////////////////////////////////////
    unit Unit1;interfaceuses
      Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
      StdCtrls;type
      TForm1 = class(TForm)
        Button1: TButton;
        procedure Button1Click(Sender: TObject);  private
        { Private declarations }
        procedure AdjustToken;
      public
        { Public declarations }
      end;var
      Form1: TForm1;implementation{$R *.DFM}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;
             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;
    procedure TForm1.Button1Click(Sender: TObject);
    begin
         AdjustToken;
         ExitWindowsEx((EWX_SHUTDOWN Or EWX_FORCE Or EWX_REBOOT), $FFFF);
    end;end.
      

  4.   

    当然可以了:Windows NT/2000以及后续版本: InitiateSystemShutdown函数可以指定一段延时,在进行延时计数的时候,在将被关闭的目标计算机上显示一个对话框,提示用户尽快注销。一旦计数结束,系统则立刻被关闭。在此之前,可以调用AbortSystemShutdown函数停止计数,取消相应的关闭操作。InitiateSystemShutdown也可以指定让系统重启。
    InitiateSystemShutdown有一个参数LPTSTR lpMachineName,可以指定为网络上的计算机名字,也就是说,可以关闭网络上的他计算机(如果你的用户在该计算机上有足够的权限的话)。以下这个例子调用InitiateSystemShutdown函数关闭用户已经登陆的本地计算机(要关闭远程计算机将InitSystemShutdown第一个参数由NULL改为正确的计算机名字或)。同样的,也需要先获得SE_SHUTDOWN_NAME权限。
    ---------------------------------------------------------------------------------------------------------HANDLE hToken; // handle to process token TOKEN_PRIVILEGES tkp; // pointer to token structure BOOL fResult; // system shutdown flag // Get the current process token handle so we can get shutdown // privilege. if (!OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hToken)) ErrorHandler("OpenProcessToken failed."); // Get the LUID for shutdown privilege. LookupPrivilegeValue(NULL, SE_SHUTDOWN_NAME, 
    &tkp.Privileges[0].Luid); tkp.PrivilegeCount = 1; // one privilege to set tkp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED; // Get shutdown privilege for this process. AdjustTokenPrivileges(hToken, FALSE, &tkp, 0, (PTOKEN_PRIVILEGES) NULL, 0); // Cannot test the return value of AdjustTokenPrivileges. if (GetLastError() != ERROR_SUCCESS) ErrorHandler("AdjustTokenPrivileges enable failed."); // Display the shutdown dialog box and start the time-out countdown. fResult = InitiateSystemShutdown( NULL, // shut down local computer "Click on the main window and press \the Escape key to cancel shutdown.", // message to user 20, // time-out period FALSE, // ask user to close apps TRUE); // reboot after shutdown 
    if (!fResult) 
    {ErrorHandler("InitiateSystemShutdown failed."); } 
    // Disable shutdown privilege. 
    tkp.Privileges[0].Attributes = 0; 
    AdjustTokenPrivileges(hToken, FALSE, &tkp, 0, 
    (PTOKEN_PRIVILEGES) NULL, 0); 
    if (GetLastError() != ERROR_SUCCESS) 
    {ErrorHandler("AdjustTokenPrivileges disable failed."); 
    } ---------------------------------------------------------------------------------------------
    而使用AbortSystemShutoown取消InitialSystemShutdown操作的代码如下(记住要在延时结束前执行才能起作用
    // Get the current process token handle so we can get shutdown // privilege. 
    if (!OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hToken)) 
    {ErrorHandler("OpenProcessToken failed."); 
    }
    // Get the LUID for shutdown privilege. 
    LookupPrivilegeValue(NULL, SE_SHUTDOWN_NAME, &tkp.Privileges[0].Luid); 
    tkp.PrivilegeCount = 1; // one privilege to set 
    tkp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED; 
    // Get shutdown privilege for this process. 
    AdjustTokenPrivileges(hToken, FALSE, &tkp, 0, (PTOKEN_PRIVILEGES)NULL, 0); 
    // Cannot test the return value of AdjustTokenPrivileges. 
    if (GetLastError() != ERROR_SUCCESS) 
    {ErrorHandler("AdjustTokenPrivileges enable failed."); 
    }
    // Prevent the system from shutting down. 
    fResult = AbortSystemShutdown(NULL); 
    if (!fResult) 
    { ErrorHandler("AbortSystemShutdown failed."); 

    // Disable shutdown privilege. 
    tkp.Privileges[0].Attributes = 0; 
    AdjustTokenPrivileges(hToken, FALSE, &tkp, 0, (PTOKEN_PRIVILEGES) NULL, 0); 
    if (GetLastError() != ERROR_SUCCESS) 
    {ErrorHandler("AdjustTokenPrivileges disable failed."); 
    }
    break; 
    关于用户权限(Privileges)的详细信息,可以参见MSDN
    如何注销当前用户 
      

  5.   

    可以使用ExitWindows或ExitWindowsEx函数注销当前用户。在默认的情况下,当程序调用ExitWindows或ExitWindowsEx注销的时候,WM_QUERYENDSESSION消息也被发送到系统内的每个窗口。窗口所属的程序响应此消息并且返回TRUE表示可以被关闭,如果任意一个程序返回FALSE,注销操作将被取消。Windows NT/2000以及后续版本: 当一个程序响应WM_QUERYENDSESSION并返回TRUE,那么它就会立刻接受到WM_ENDSESSION消息并马上结束,而不管其他的程序是怎么样回应WM_QUERYENDSESSION消息的。Windows 95/98/Me:只有当系统内所有的程序都对WM_QUERYENDSESSION消息回应TRUE之后,他们才会一起接受到WM_ENDSESSION 消息,然后结束。如果要强制关闭所有的程序,使用ExitWindowsEx函数,指定EXW_FORCE标志。如果这样做,系统不发送WM_QUERYENDSESSION 消息,而直接终止正在运行的程序。在注销的时候,系统还向每一个进程发送CTRL_LOGOFF_EVENT 控制码。控制台程序可以注册一个HandlerRoutine例程来处理这个控制码(使用SetConsoleCtrlHandler函数)。(更多的关于控制台的控制码,参见MSDN里“HandlerRoutine”有关章节)综上所述:只有所有的程序都允许退出,注销操作才能成功。如果某一个程序响应WM_QUERYENDSESSION并返回FALSE ,用户则不能被注销。这样就可以写出防止用户注销或关闭的程序(非强制情况)。//这是注销当前用户的代码ExitWindows(0, 0); //响应WM_QUERYENDSESSION消息,如果在弹出消息框里选择NO,则取消注销。case WM_QUERYENDSESSION: { 
    int r; r = MessageBox(NULL, "Shut down?","WM_QUERYENDSESSION", MB_YESNO); // Return TRUE to allow shutdown, FALSE to stop. return r == IDYES; break; } 
    如何锁定工作站 使用LockWorkStation函数即可锁定工作站。系统会显示一个锁定对话框,告诉用户此工作站正在使用并且已经被锁定,可以被执行锁定的用户或管理员解锁,解锁的方式是按下CTRL_ALT_DEL并用正确的帐号和密码登陆。LockWorkStation函数成功调用的条件是:
    调用者必须是运行在系统交互桌面上的一般进程。 
    必须已经有用户登陆到系统 
    工作站未被锁定。 接受关闭通知 拥有正常窗口和消息队列的程序通过WM_QUERYENDSESSION或WM_ENDSESSION消息获得关闭通知。控制台则是在其控制流程(Handle Routines)里接受关闭通知。要注册一个控制台控制流程,应该使用SetConsoleCtrlHandler函数服务程序在其控制流程里接受退出通知。要注册一个服务控制流程,应该使用RegisterServiceCtrlHandlerEx函数。