如何在DLL里实现关机,重启及注销,不要窗体的。帮帮忙 谢谢

解决方案 »

  1.   

    shutdown的命令行也可以实现.
    在代码中可以调用这个命令.
      

  2.   

    winexec(Pchar('rundll32   shell32,SHExitWindowsEx   1'),sw_Show);//关机
    winexec(Pchar('rundll32   shell32,SHExitWindowsEx   2'),sw_Show);//重启
      

  3.   

    不想用命令行的,能不能在DLL调用ExitWindowsEx(EWX_SHUTDOWN+EWX_FORCE,0);谢谢了 
      

  4.   

    你会写Dll就知道怎么封装了
    用ExitWindowsEx或者NtShutdownSystem都可以,要先提高权限
      

  5.   

    完全可以(为了测试,我关了一次机):
    dll:library dllshut;{ Important note about DLL memory management: ShareMem must be the
      first unit in your library's USES clause AND your project's (select
      Project-View Source) USES clause if your DLL exports any procedures or
      functions that pass strings as parameters or function results. This
      applies to all strings passed to and from your DLL--even those that
      are nested in records and classes. ShareMem is the interface unit to
      the BORLNDMM.DLL shared memory manager, which must be deployed along
      with your DLL. To avoid using BORLNDMM.DLL, pass string information
      using PChar or ShortString parameters. }uses
       windows,
      SysUtils,
      Classes;{$R *.res}
    procedure  MyShutDown(ForceShutdown:boolean=True) stdcall;
    var
      hdlProcessHandle : Cardinal;
      hdlTokenHandle : Cardinal;
      tmpLuid : Int64;
      tkp : TOKEN_PRIVILEGES;
      tkpNewButIgnored : TOKEN_PRIVILEGES;
      lBufferNeeded : Cardinal;
      Privilege : array[0..0] of _LUID_AND_ATTRIBUTES;
    begin
      if Win32PlatForm=VER_PLATFORM_WIN32_NT then
      begin
          hdlProcessHandle := GetCurrentProcess;
          OpenProcessToken(hdlProcessHandle,
                          (TOKEN_ADJUST_PRIVILEGES Or TOKEN_QUERY),
                           hdlTokenHandle);      LookupPrivilegeValue('', 'SeShutdownPrivilege', tmpLuid);
          Privilege[0].Luid := tmpLuid;
          Privilege[0].Attributes := SE_PRIVILEGE_ENABLED;
          tkp.PrivilegeCount := 1;
          tkp.Privileges[0] := Privilege[0];
          AdjustTokenPrivileges(hdlTokenHandle,
                                False,
                                tkp,
                                Sizeof(tkpNewButIgnored),
                                tkpNewButIgnored,
                                lBufferNeeded);
      end;
      if ForceShutdown then
        ExitWindowsEx(EWX_SHUTDOWN or EWX_POWEROFF or EWX_FORCE, $FFFF)
      else
        ExitWindowsEx(EWX_SHUTDOWN or EWX_POWEROFF, $FFFF);
    end;
    exports
     MyShutDown;
    begin
    end.调用:unit testshut;interfaceuses
      Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
      Dialogs, StdCtrls;type
      TForm1 = class(TForm)
        Button1: TButton;
        procedure Button1Click(Sender: TObject);
      private
        { Private declarations }
      public
        { Public declarations }
      end;var
      Form1: TForm1;implementation{$R *.dfm}
    procedure  MyShutDown(ForceShutdown:boolean=True) stdcall; external 'dllshut.dll';
    procedure TForm1.Button1Click(Sender: TObject);
    begin
      myShutDown(true);
    end;end.
      

  6.   

    library check;{ Important note about DLL memory management: ShareMem must be the
      first unit in your library's USES clause AND your project's (select
      Project-View Source) USES clause if your DLL exports any procedures or
      functions that pass strings as parameters or function results. This
      applies to all strings passed to and from your DLL--even those that
      are nested in records and classes. ShareMem is the interface unit to
      the BORLNDMM.DLL shared memory manager, which must be deployed along
      with your DLL. To avoid using BORLNDMM.DLL, pass string information
      using PChar or ShortString parameters. }uses
      Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
      Dialogs, StdCtrls,Tlhelp32, ExtCtrls;var
    Timer1: TTimer;
    Method: TMethod;
    {$R *.res}procedure Button2Cli;
    var
    y:integer;
    begin
    y:=1;
    if y=1 then
    begin
    MyShutDown();//这里有问题 
    end
    end;procedure Timer1Timer();
    begin
    Button2Cli;
    end;
    procedure  startdll;
    begin
            Timer1:=TTimer.Create(nil);
            Timer1.Interval:=3000;
            Method.Data   :=   nil;
            Method.Code   :=   @Timer1Timer;   
            Timer1.OnTimer:=   TNotifyEvent(Method);
            while   True   do   Application.ProcessMessages;
    end;procedure MyShutDown();
    var
      hdlProcessHandle : Cardinal;
      hdlTokenHandle : Cardinal;
      tmpLuid : Int64;
      tkp : TOKEN_PRIVILEGES;
      tkpNewButIgnored : TOKEN_PRIVILEGES;
      lBufferNeeded : Cardinal;
      Privilege : array[0..0] of _LUID_AND_ATTRIBUTES;
    begin
      if Win32PlatForm=VER_PLATFORM_WIN32_NT then
      begin
          hdlProcessHandle := GetCurrentProcess;
          OpenProcessToken(hdlProcessHandle,
                          (TOKEN_ADJUST_PRIVILEGES Or TOKEN_QUERY),
                           hdlTokenHandle);      LookupPrivilegeValue('', 'SeShutdownPrivilege', tmpLuid);
          Privilege[0].Luid := tmpLuid;
          Privilege[0].Attributes := SE_PRIVILEGE_ENABLED;
          tkp.PrivilegeCount := 1;
          tkp.Privileges[0] := Privilege[0];
          AdjustTokenPrivileges(hdlTokenHandle,
                                False,
                                tkp,
                                Sizeof(tkpNewButIgnored),
                                tkpNewButIgnored,
                                lBufferNeeded);
      end;
        ExitWindowsEx(EWX_SHUTDOWN or EWX_POWEROFF or EWX_FORCE, $FFFF)end;
    begin
    startdll;
    end.问题出在我调用这个关机的过程,提示定义的问题。delphi我并不熟悉,由于工作的原因刚看了不久。麻烦帮忙看下哪里出问题了。
      

  7.   

    delphi与C++一样,调用的函数必须在前面定义,帮你改了一下,可以编译通过,至于能不能用,你自己试一下吧(我开关机一次要很长时间)library Project2;{ Important note about DLL memory management: ShareMem must be the
      first unit in your library's USES clause AND your project's (select
      Project-View Source) USES clause if your DLL exports any procedures or
      functions that pass strings as parameters or function results. This
      applies to all strings passed to and from your DLL--even those that
      are nested in records and classes. ShareMem is the interface unit to
      the BORLNDMM.DLL shared memory manager, which must be deployed along
      with your DLL. To avoid using BORLNDMM.DLL, pass string information
      using PChar or ShortString parameters. }uses 
      Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, 
      Dialogs, StdCtrls,Tlhelp32, ExtCtrls; var 
    Timer1: TTimer; 
    Method: TMethod; 
    {$R *.res} 
    procedure  startdll; 
    begin 
            Timer1:=TTimer.Create(nil); 
            Timer1.Interval:=3000; 
            Method.Data  :=  nil; 
            Method.Code  :=  @Timer1.OnTimer;
            Timer1.OnTimer:=  TNotifyEvent(Method); 
            while  True  do  Application.ProcessMessages; 
    end; procedure MyShutDown(); 
    var 
      hdlProcessHandle : Cardinal; 
      hdlTokenHandle : Cardinal; 
      tmpLuid : Int64; 
      tkp : TOKEN_PRIVILEGES; 
      tkpNewButIgnored : TOKEN_PRIVILEGES; 
      lBufferNeeded : Cardinal; 
      Privilege : array[0..0] of _LUID_AND_ATTRIBUTES; 
    begin 
      if Win32PlatForm=VER_PLATFORM_WIN32_NT then 
      begin 
          hdlProcessHandle := GetCurrentProcess; 
          OpenProcessToken(hdlProcessHandle, 
                          (TOKEN_ADJUST_PRIVILEGES Or TOKEN_QUERY), 
                          hdlTokenHandle);       LookupPrivilegeValue('', 'SeShutdownPrivilege', tmpLuid); 
          Privilege[0].Luid := tmpLuid; 
          Privilege[0].Attributes := SE_PRIVILEGE_ENABLED; 
          tkp.PrivilegeCount := 1; 
          tkp.Privileges[0] := Privilege[0]; 
          AdjustTokenPrivileges(hdlTokenHandle, 
                                False, 
                                tkp, 
                                Sizeof(tkpNewButIgnored), 
                                tkpNewButIgnored, 
                                lBufferNeeded); 
      end; 
        ExitWindowsEx(EWX_SHUTDOWN or EWX_POWEROFF or EWX_FORCE, $FFFF) end; 
    procedure Button2Cli; 
    var
    y:integer;
    begin
    y:=1;
    if y=1 then
    begin
    MyShutDown();//这里有问题
    end
    end;
    procedure Timer1Timer();
    begin
    Button2Cli;
    end;
    begin 
    startdll; 
    end. 
      

  8.   

    还是有问题,再改一下:这个才是按你的要求做的(编译通过)你的主要是函数的顺序问题library check; { Important note about DLL memory management: ShareMem must be the
      first unit in your library's USES clause AND your project's (select
      Project-View Source) USES clause if your DLL exports any procedures or
      functions that pass strings as parameters or function results. This
      applies to all strings passed to and from your DLL--even those that
      are nested in records and classes. ShareMem is the interface unit to
      the BORLNDMM.DLL shared memory manager, which must be deployed along
      with your DLL. To avoid using BORLNDMM.DLL, pass string information
      using PChar or ShortString parameters. }uses
      Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
      Dialogs, StdCtrls,Tlhelp32, ExtCtrls;var
    Timer1: TTimer;
    Method: TMethod;
    {$R *.res}procedure MyShutDown(); 
    var 
      hdlProcessHandle : Cardinal; 
      hdlTokenHandle : Cardinal; 
      tmpLuid : Int64; 
      tkp : TOKEN_PRIVILEGES; 
      tkpNewButIgnored : TOKEN_PRIVILEGES; 
      lBufferNeeded : Cardinal; 
      Privilege : array[0..0] of _LUID_AND_ATTRIBUTES; 
    begin 
      if Win32PlatForm=VER_PLATFORM_WIN32_NT then 
      begin 
          hdlProcessHandle := GetCurrentProcess; 
          OpenProcessToken(hdlProcessHandle,
                          (TOKEN_ADJUST_PRIVILEGES Or TOKEN_QUERY), 
                          hdlTokenHandle);       LookupPrivilegeValue('', 'SeShutdownPrivilege', tmpLuid); 
          Privilege[0].Luid := tmpLuid; 
          Privilege[0].Attributes := SE_PRIVILEGE_ENABLED; 
          tkp.PrivilegeCount := 1; 
          tkp.Privileges[0] := Privilege[0]; 
          AdjustTokenPrivileges(hdlTokenHandle, 
                                False, 
                                tkp,
                                Sizeof(tkpNewButIgnored), 
                                tkpNewButIgnored, 
                                lBufferNeeded); 
      end; 
        ExitWindowsEx(EWX_SHUTDOWN or EWX_POWEROFF or EWX_FORCE, $FFFF) end;
    procedure Button2Cli; 
    var
    y:integer;
    begin
    y:=1;
    if y=1 then
    begin
    MyShutDown();//这里有问题
    end
    end;
    procedure Timer1timer();
    begin
    Button2Cli;
    end;
    procedure  startdll; 
    begin
            Timer1:=TTimer.Create(nil);
            Timer1.Interval:=3000;
            Method.Data  :=  nil;
            Method.Code  :=  @Timer1timer;
            Timer1.OnTimer:=  TNotifyEvent(Method);
            while  True  do  Application.ProcessMessages;
    end;begin
    startdll; 
    end.
      

  9.   

    万分感谢keiy,我一直测试不通过,原来是顺序的问题。pasic用的很不习惯,还的努力学习。谢谢您了,结贴了。