用Windows API函数:ExitWindowsEx,注意要有相应的权限。
解决方案 »
- 关于bookmark的问题,请高手指教!
- 如何实现在菜单栏下拉菜单中显示当前打开的窗口,谢谢
- 在后台添加一个新数据库的代码怎么写啊?
- 请问谁会给程序加密码,怎么加阿?
- 开发企业管理软件,比如:进销存,采用C++BUILDER和DELPHI和VB哪一样更好??
- 关于SMTP验证的问题,请大家指教:0
- 为什么我的visual studio.net不能建立新项目??
- 谁用过formula one的表格控件,能不能大概给我讲讲怎么用?
- 请问我在用Datagrid控件时,我开始不绑定数据,可缺省只有两列,怎样让它显示多列(我可以先把标题设上)?谢谢,加分!!!
- 怎么给回答我问题的人分数
- 哪里可以邮购王国荣的vbapi
- 这个问题以前好象有人提过,不知道各位还是否愿意帮小弟一把
ExitWindowsEx VB声明
Declare Function ExitWindowsEx Lib "user32" Alias "ExitWindowsEx" (ByVal uFlags As Long, ByVal dwReserved As Long) As Long
说明
退出windows,并用特定的选项重新启动
返回值
Long,非零表示成功,零表示失败。会设置GetLastError
参数表
参数 类型及说明
uFlags Long,指定下述一个或多个标志(用OR运算符合并到一起)
EWX_FORCE 强迫中止没有响应的进程
EWX_LOGOFF 中止进程,然后注销
EWX_SHUTDOWN 关掉系统电源(如果可能的话,ATX电源就可以)
EWX_REBOOT 重新引导系统
EWX_SHUTDOWN 关闭系统
dwReserved Long,保留,设为零
注解
这个函数调用后会立刻返回,系统关闭过程是在后台进行的。注意先中止自己的应用程序,使关闭过程更显平顺。当然,您的进程必须有足够的优先权,否则也不能执行这种操作
ExitWindowsEx Flags, 0
End Function
编译后,在Windows 2000 用ASP调用该DLL的ExitWindows方法,一点反应都没有,在XP中能重新启动机器。这是为什么??在windwos 2000如何设置权限(我在IIS中已经去掉匿名访问了,访问时输入管理员的口令,都不能重新启动2000。)?
————————————————————————————————————
远程如何关闭NT服务器---- 2000年7月24日出版的《计算机世界》周报的《企业&人.COM》版曾刊登过《用Delphi实现远程控制》 一文,其中提到过远程关闭计算机,经笔者实验,得到了较好的效果,但当进行远程关闭WindowsNT服务器(以下简称NT服务器)时,却没有实现,该文作者也没有说明此类情况,而实际上这是由于NT服务系统的安全措施决定的。NT服务器通过用户权限策略,使得对它的访问控制比较严格,它必须由系统管理员分配给用户一定权限后才能管理计算机的资源,在NT中这种权限有很多种,如:更改系统时间要有SE_SYSTEMTIME_NAME的权限、关闭系统必须要有SE_SHUTDOWN_NAME的权限,没有得到关闭计算机的这种权限则不能关闭NT服务器,因此只要我们获得了这一权限后即可关闭NT服务器了。笔者利用这种思路,通过查阅有关资料,终于成功地利用上面一文中提到的方法实现了远程关闭NT服务器。 ---- 一、要想取得关闭NT服务器的权限,需要用到五个API函数,函数的作用及参数分别说明如下: 1、GetCurrentProcess:该函数无参数,用来获得当前进程的句柄。2、OpenProcessToken(ProcessHandle: THandle;
DesiredAccess: DWORD;
var TokenHandle: THandle): BOOL; stdcall;
打开一个进程中相关联的访问标志。
ProcessHandle:进程句柄;
DesiredAccess:需要的访问标志;
TokenHandle: 返回访问标志的句柄 3、LookupPrivilegeValue(lpSystemName, lpName: PChar;
var lpLuid: TLargeInteger): BOOL; stdcall;
指定某一权限名字后,该函数返回一个标识符,即LUID。
lpSystemName:指定要查找权限的系统名字,当设为空字符时,指本地系统;
lpName:指定权限的名称;
lpLuid:返回指定权限的标识号;4、AdjustTokenPrivileges(TokenHandle: THandle;
DisableAllPrivileges: BOOL;
const NewState: TTokenPrivileges; BufferLength:
DWORD;
var PreviousState: TTokenPrivileges; var ReturnLength:
DWORD): BOOL; stdcall; overload;
修改指定访问标志的权限,即设置该权限能或不能。
TokenHandle:所访问的权限标记句柄;
DisableAllPrivileges:设置权限能还是不能;
NewState:新的权限信息;
BufferLength:原有权限的缓冲区大小;
PreviousState:权限的原有状态;
ReturnLength:返回的字节。 5、另外一个函数则是关闭系统的函数ExitWindowEx(),
该函数在上面提到的一文中已讲过,在此只列出它的第一个
参数及说明(括号内为该常量的值),函数的后面一个参数为保留,可设为0。
EWX_LOGOFF(0):重新登录。
EWX_SHUTDOWN(1):关闭系统并出现"现在可以安全的关机了"。
EWX_REBOOT(2):重新启动计算机。
EWX_FORCE(4):强制关闭程序,它有可能使应用程序丢失数据,要小心使用。
EWX_POWEROFF(8):关闭系统和电源,主板须支持该功能才有效。---- 注:(1)、以上参数中,除了EWX_LOGOFF在Windows95/98和NT服务中直接使用外,其余的参数在NT系统中,必须要取得SE_SHUTDOWN_NAME 权限才有效。 ---- (2)、参数EWX_FORCE可以和其它参数配合使用。 ---- 二、为了在其它应用软件中能够方便使用,可以把设置权限这个过程封装成一个函数,以后我们只需调用它,输入相应的权限名后,即可获得该权限。该函数的代码如下: function SetPrivilege(PrivilegeName: String; Enable:
Boolean): Boolean;
//PrivilegeName指想要获得权限的常量,
如果想要取得其它相应的权限只需要输入相应的常量。
//关闭系统的常量是SeShutdownPrivilege,
该常量在Delphi中没有声明。
var
NewState,
PreviousState : TTokenPrivileges;
token : THandle;
dwRetLen : DWord;
begin
Result := False;
OpenProcessToken(GetCurrentProcess,
TOKEN_ADJUST_PRIVILEGES or TOKEN_QUERY, token);
NewState.PrivilegeCount := 1;
if LookupPrivilegeValue(nil, PChar(PrivilegeName),
NewState.Privileges[0].LUID) then
begin
if Enable then
NewState.Privileges[0].Attributes :
= SE_PRIVILEGE_ENABLED
else
NewState.Privileges[0].Attributes := 0;
dwRetLen := 0;
Result := AdjustTokenPrivileges(token,
False, NewState, SizeOf(PreviousState),
PreviousState, dwRetLen);
end;
CloseHandle(token);
end;---- 三、此外还要获取当前的操作系统,以便采取不同的关机方式。通过自定义函数判断当前的操作系统,函数代码如下: function GetWinVer:Byte;
var OS:TOSVersionInfo;
begin
OS.dwOSVersionInfoSize := SizeOf(TOSVersionInfo);
GetVersionEx(OS);
case OS.dwPlatformId of
VER_PLATFORM_WIN32s : Result:=0; //Windows 3.1x/32s
VER_PLATFORM_WIN32_WINDOWS : Result:=1; //Windows 95
VER_PLATFORM_WIN32_NT : Result:=2; //Windows NT
end;
end;---- 四、改写上面提到过的一文中关闭系统的那一段代码(在被控程序中)。 procedure TForm1.ServerSocket1ClientRead(Sender: TObject;
Socket: TCustomWinSocket);
var
Str:PChar;
Code,V:Integer;
begin
Str:=PChar(Socket.ReceiveText);
Val(Str,V,Code);
if Code< >0 then
Application.MessageBox(Str,'提示信息',
MB_OK+MB_ICONINFORMATION)
else
if (V=0)or(V=1)or(V=2)or(V=8) then begin
//v=8为添加上去的,指关闭电源
if GetWinVer=2 then begin //如果当前系统是Windows NT
SetPrivilege('SeShutdownPrivilege', True);
if not ExitWindowsEx(V, 0) then
SetPrivilege('SeShutdownPrivilege', False);
end else
ExitWindowsEx(V,0);
end else
Application.MessageBox(Str,'提示信息',
MB_OK+MB_ICONINFORMATION);
end;---- 上述程序用Delphi5编写在Win98中文版和Windows NT4.0中文版局域网中运行通过。特别声明:在实验时一定要注意数据的安全,以免造成不良后果。