如何在程序中强制关机?(200分)

  • 主题发起人 主题发起人 LuJuhe
  • 开始时间 开始时间
L

LuJuhe

Unregistered / Unconfirmed
GUEST, unregistred user!
想写一个UPS管理系统:停电后,检查UPS的电池容量,容量小于一定值时通知网络上的所有<br>服务器按一定顺序关机。<br><br>现在的问题是:应该调用什么API让系统关机,以及遇到有时某些程序会造成系统无法关机<br>时,如何检测这种状态并强制性地让系统安全关机?
 
以下转载:<br>================================================================================<br><br>如何重启或关闭NT &nbsp;<br>Kingron<br>摘 要:如何重启或关闭NT<br>关键字:NT 重启 关闭<br>类 别:系统控制<br>&nbsp;<br>在NT中跟Win9x下是一样的。关键是要有关机的权限!<br>在调用关机的函数之前请调用下面的函数就可以了: <br><br>procedure AdjustToken; <br>var<br>&nbsp; hdlProcessHandle : Cardinal;<br>&nbsp; hdlTokenHandle : Cardinal;<br>&nbsp; tmpLuid : Int64;<br>&nbsp; tkpPrivilegeCount : Int64;<br>&nbsp; tkp : TOKEN_PRIVILEGES;<br>&nbsp; tkpNewButIgnored : TOKEN_PRIVILEGES;<br>&nbsp; lBufferNeeded : Cardinal;<br>&nbsp; Privilege : array[0..0] of _LUID_AND_ATTRIBUTES; <br>begin<br>&nbsp; &nbsp; &nbsp; &nbsp; hdlProcessHandle := GetCurrentProcess;<br>&nbsp; &nbsp; &nbsp; &nbsp; OpenProcessToken(hdlProcessHandle,<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; (TOKEN_ADJUST_PRIVILEGES Or TOKEN_QUERY),<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; hdlTokenHandle);<br>&nbsp; &nbsp; &nbsp; &nbsp; // Get the LUID for shutdown privilege.<br>&nbsp; &nbsp; &nbsp; &nbsp; LookupPrivilegeValue('', 'SeShutdownPrivilege', tmpLuid);<br>&nbsp; &nbsp; &nbsp; &nbsp; Privilege[0].Luid := tmpLuid;<br>&nbsp; &nbsp; &nbsp; &nbsp; Privilege[0].Attributes := SE_PRIVILEGE_ENABLED;<br>&nbsp; &nbsp; &nbsp; &nbsp; tkp.PrivilegeCount := 1; // One privilege to set<br>&nbsp; &nbsp; &nbsp; &nbsp; tkp.Privileges[0] := Privilege[0];<br>&nbsp; &nbsp; &nbsp; &nbsp; // Enable the shutdown privilege in the access token of this<br>&nbsp; &nbsp; &nbsp; &nbsp; // process.<br>&nbsp; &nbsp; &nbsp; &nbsp; AdjustTokenPrivileges(hdlTokenHandle,<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; False,<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; tkp,<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; Sizeof(tkpNewButIgnored),<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; tkpNewButIgnored,<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; lBufferNeeded); <br><br>end;<br><br>强制关机 ExitWindowsEx(EWX_SHUTDOWN or EWX_FORCE,0);<br>强制重启 ExitWindowsEx(EWX_REBOOT OR EWX_FORCE,0);<br>重新登录 ExitWindowsEx(EWX_LOGOFF,0);
 
function My_ExitWindows(M_1Reboot_2Power: integer): Boolean; //重启(M:=1).关机(M:=2)<br>var<br>hToken: THANDLE;<br>hProc: THANDLE;<br>mLUID: TLargeInteger;<br>mPriv, mNewPriv: TOKEN_PRIVILEGES;<br>mBufferLength: DWord;<br>begin<br>Result:=false;<br>if not (M_1Reboot_2Power in [1, 2]) then exit;<br>hProc := GetCurrentProcess();<br>OpenProcessToken(hProc, TOKEN_ADJUST_PRIVILEGES + TOKEN_QUERY, hToken);<br>LookupPrivilegeValue('', 'SeShutdownPrivilege', mLUID);<br>mPriv.PrivilegeCount := 1;<br>mPriv.Privileges[0].Attributes := SE_PRIVILEGE_ENABLED;<br>mPriv.Privileges[0].Luid := mLUID;<br>AdjustTokenPrivileges(hToken, False, mPriv, (4 + (12 * mPriv.PrivilegeCount)), mNewPriv, mBufferLength);<br>GetLastError;<br>case M_1Reboot_2Power of<br>1: Result := ExitWindowsEx(EWX_FORCE+EWX_REBOOT,0);<br>2: Result := ExitWindowsEx(EWX_FORCE+EWX_POWEROFF, 0);<br>end;<br>end;<br>
 
我是准备让它作为NT Service运行的,LocalSystem用户,应该不需要调整权限吧。<br><br>
 
多人接受答案了。
 
后退
顶部