完全可以(为了测试,我关了一次机): 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.
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我并不熟悉,由于工作的原因刚看了不久。麻烦帮忙看下哪里出问题了。
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.
还是有问题,再改一下:这个才是按你的要求做的(编译通过)你的主要是函数的顺序问题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.
在代码中可以调用这个命令.
winexec(Pchar('rundll32 shell32,SHExitWindowsEx 2'),sw_Show);//重启
用ExitWindowsEx或者NtShutdownSystem都可以,要先提高权限
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.
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我并不熟悉,由于工作的原因刚看了不久。麻烦帮忙看下哪里出问题了。
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.
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.