请问在WIN2000下如何实现软件关机,并且关闭电源(50分)

  • 主题发起人 主题发起人 星月
  • 开始时间 开始时间

星月

Unregistered / Unconfirmed
GUEST, unregistred user!
我使用API ExWindowsEx 函数的时候。系统确实实现关机了。<br>但是最后留给我一个对话框,告诉我可以关闭电源了。我还得手动关闭电源。<br>我在注册表里已经把PowerDownAfterShutDown 给置1了。<br>可是还是不能自动关闭电源。<br><br>我使用开始-》关机,就可以关闭系统和电源。并且不受 PowerDownAfterShutDown的限制。<br>我还想问问这个健值到地起什么作用。<br>谢谢!
 
没办法,从nt起就无法软件关电源了。<br>
 
首先,如果你在win2000的开始菜单中关闭系统,计算机能关闭电源,<br>即主板支持,使用下面函数即可。<br>这是我以前的回答http://www.delphibbs.com/delphibbs/dispq.asp?lid=414648<br>再给你回答一遍<br><br>win2000和nt的关机机制和win98不一样<br>必须调用AdjustTokenPrivileges使se_shutdown_name有效<br>unit Unit1;<br><br>interface<br><br>uses<br>&nbsp; Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,<br>&nbsp; StdCtrls;<br><br>type<br>&nbsp; TForm1 = class(TForm)<br>&nbsp; &nbsp; Button1: TButton;<br>&nbsp; &nbsp; Memo1: TMemo;<br>&nbsp; &nbsp; Button2: TButton;<br>&nbsp; &nbsp; procedure Button1Click(Sender: TObject);<br>&nbsp; &nbsp; procedure Button2Click(Sender: TObject);<br>&nbsp; private<br>&nbsp; &nbsp; procedure DoShutdown;<br>&nbsp; &nbsp; { Private declarations }<br>&nbsp; public<br>&nbsp; &nbsp; { Public declarations }<br>&nbsp; end;<br><br>var<br>&nbsp; Form1: TForm1;<br>&nbsp; &nbsp;logoff: boolean = false;<br>&nbsp; &nbsp;reboot: boolean = false;<br>&nbsp; &nbsp;warn: boolean = false;<br>&nbsp; &nbsp;downQuick: boolean = false;<br>&nbsp; &nbsp;cancelShutdown: boolean = false;<br>&nbsp; &nbsp;powerOff: boolean = false;<br>&nbsp; &nbsp;timeDelay: integer = 0;<br><br><br>implementation<br><br>{$R *.DFM}<br><br>function HasParam(Opt: Char): Boolean;<br>var <br>&nbsp; &nbsp;x: integer; <br>begin <br>&nbsp; &nbsp; &nbsp;result := false; <br>&nbsp; &nbsp; &nbsp;for x := 1 to paramCount do <br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;if (paramstr(x) = '-'+opt) or (paramstr(x) = '/'+opt) then result := true; <br>end; <br><br>function GetErrorString: String; <br>var <br>&nbsp; &nbsp;lz: Cardinal; <br>&nbsp; &nbsp;err: array[0..512] of Char; <br>begin <br>&nbsp; &nbsp; &nbsp;lz := GetLastError; <br>&nbsp; &nbsp; &nbsp;FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, nil, lz, 0, @err, 512, nil);<br>&nbsp; &nbsp; &nbsp;result := string(err);<br>end; <br><br>procedure Tform1.DoShutdown;<br>var <br>&nbsp; &nbsp;rl,flgs: Cardinal; <br>&nbsp; &nbsp;hToken: Cardinal; <br>&nbsp; &nbsp;tkp: TOKEN_PRIVILEGES; <br>begin <br>&nbsp; &nbsp; &nbsp;flgs := 0; <br>&nbsp; &nbsp; &nbsp;if downQuick then flgs := flgs or EWX_FORCE; <br>&nbsp; &nbsp; &nbsp;if not reboot then flgs := flgs or EWX_SHUTDOWN; <br>&nbsp; &nbsp; &nbsp;if reboot then flgs := flgs or EWX_REBOOT; <br>&nbsp; &nbsp; &nbsp;if poweroff and (not reboot) then flgs := flgs or EWX_POWEROFF; <br>&nbsp; &nbsp; &nbsp;if logoff then flgs := (flgs and (not (EWX_REBOOT or EWX_SHUTDOWN or EWX_POWEROFF))) or EWX_LOGOFF; <br>&nbsp; &nbsp; &nbsp;if Win32Platform = VER_PLATFORM_WIN32_NT then begin <br>&nbsp; &nbsp; &nbsp; &nbsp; if not OpenProcessToken(GetCurrentProcess, TOKEN_ADJUST_PRIVILEGES or TOKEN_QUERY, hToken) then <br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;memo1.lines.add('Cannot open process token. ['+GetErrorString+']')<br>&nbsp; &nbsp; &nbsp; &nbsp; else begin<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;if LookupPrivilegeValue(nil, 'SeShutdownPrivilege', tkp.Privileges[0].Luid) then begin <br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;tkp.Privileges[0].Attributes := SE_PRIVILEGE_ENABLED;<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;tkp.PrivilegeCount := 1;<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;AdjustTokenPrivileges(hToken, False, tkp, 0, nil, rl);<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;if GetLastError &lt;&gt; ERROR_SUCCESS then <br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;memo1.lines.add('Error adjusting process privileges.'); <br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;end else memo1.lines.add('Cannot find privilege value. ['+GetErrorString+']');<br>&nbsp; &nbsp; &nbsp; &nbsp; end;<br>&nbsp; &nbsp; &nbsp; &nbsp; if CancelShutdown then<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;if AbortSystemShutdown(nil) = False then <br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; memo1.lines.add('Cannot abort. [/'+GetErrorString+'/]')<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;else <br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;memo1.lines.add('Cancelled./')<br>&nbsp; &nbsp; &nbsp; &nbsp; else begin <br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;if InitiateSystemShutdown(nil, nil, timeDelay, downQuick, Reboot) = False then<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; memo1.lines.add('Cannot go down. [/'+GetErrorString+'/]')<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;else <br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;memo1.lines.add('Shutting down!/'); <br>&nbsp; &nbsp; &nbsp; &nbsp; end;<br>&nbsp; &nbsp; &nbsp;end <br>&nbsp; &nbsp; &nbsp;else begin<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ExitWindowsEx(flgs, 0); <br>&nbsp; &nbsp; &nbsp;end; <br>end; <br><br>procedure TForm1.Button1Click(Sender: TObject);<br>begin<br>&nbsp; &nbsp; &nbsp;memo1.lines.add('Shutdown v0.3 for Win32 (similar to the Linux version)');<br>&nbsp; &nbsp; &nbsp;memo1.lines.add('(c) 2000 NeuralAbyss Software. All Rights Reserved.');<br>&nbsp; &nbsp; &nbsp;if HasParam('?') or (ParamCount=0) then begin<br>&nbsp; &nbsp; &nbsp; &nbsp; memo1.lines.add('Usage: &nbsp; &nbsp;shutdown [-akrhfnc] [-t secs]');<br>&nbsp; &nbsp; &nbsp; &nbsp; memo1.lines.add(' &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;-k: &nbsp; &nbsp; &nbsp;don''t really shutdown, only warn.');<br>&nbsp; &nbsp; &nbsp; &nbsp; memo1.lines.add(' &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;-r: &nbsp; &nbsp; &nbsp;reboot after shutdown.');<br>&nbsp; &nbsp; &nbsp; &nbsp; memo1.lines.add(' &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;-h: &nbsp; &nbsp; &nbsp;halt after shutdown.');<br>&nbsp; &nbsp; &nbsp; &nbsp; memo1.lines.add(' &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;-p: &nbsp; &nbsp; &nbsp;power off after shutdown');<br>&nbsp; &nbsp; &nbsp; &nbsp; memo1.lines.add(' &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;-l: &nbsp; &nbsp; &nbsp;log off only');<br>&nbsp; &nbsp; &nbsp; &nbsp; memo1.lines.add(' &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;-n: &nbsp; &nbsp; &nbsp;kill apps that don''t want to die.');<br>&nbsp; &nbsp; &nbsp; &nbsp; memo1.lines.add(' &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;-c: &nbsp; &nbsp; &nbsp;cancel a running shutdown.');<br>&nbsp; &nbsp; &nbsp;end else begin<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;if HasParam('k') then warn := true;<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;if HasParam('r') then reboot := true;<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;if HasParam('h') and reboot then begin<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; memo1.lines.add('Error: Cannot specify -r and -h parameters together!');<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; Exit;<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;end;<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;if HasParam('h') then reboot := false;<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;if HasParam('n') then downQuick := true;<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;if HasParam('c') then cancelShutdown := true;<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;if HasParam('p') then powerOff := true;<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;if HasParam('l') then logoff := true;<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;DoShutdown;<br>&nbsp; &nbsp; &nbsp;end;<br>end;<br>procedure TForm1.Button2Click(Sender: TObject);<br>begin<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; reboot := true;<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; DoShutdown;<br><br>end;<br>end.<br>
 
cactus123456,我已经使用AdjustTokenPrivileges设置权限了。关机可以。<br>可就是关机完后显示哪个讨厌的“你现在可以关闭电源了”这个对话框。<br>你的代码我试试。
 
cactus123456 你的程序我试了。还是不行。还是出现那个讨厌的告诉我关闭电源的对话框。<br><br>是不是WIN2000真的象sonie说的那样。真的不支持软件关机啊?
 
W2K是肯定可以软件关机的,我曾经写了个代码,先设置特权,然后调用ExitWindows,<br>我找一下,看能不能找到我的源码;我记得不用几行代码的,。
 
关机是能实现的,但关电源,hehe....<br><br><br>这里不关权限的问题
 
我想WIN2K一定能实现软件关电源!!<br><br>要不我们点开始-》关机 后,系统怎么关的电源呢?那不也是软件关电源嘛。<br><br>请各位富翁帮帮忙呀?我很着急呀。小弟先谢谢了。
 
function ShutDown(uFlags: Cardinal):boolean;<br>const<br>&nbsp; ADJUST_PRIV = TOKEN_QUERY or TOKEN_ADJUST_PRIVILEGES;<br>&nbsp; SHTDWN_PRIV = 'SeShutdownPrivilege';<br>&nbsp; PRIV_SIZE &nbsp; = sizeOf(TTokenPrivileges);<br><br>var<br>&nbsp; Len: DWORD;<br>&nbsp; TokenPriv, Dummy: TTokenPrivileges;<br>&nbsp; Token: THandle;<br>&nbsp; Error:integer;<br>begin<br>&nbsp; error:=0;<br>&nbsp; // 设置特权<br>&nbsp; // Delphi2:<br>&nbsp; //if not OpenProcessToken(GetCurrentProcess(), ADJUST_PRIV, @Token) then<br>&nbsp; if not OpenProcessToken(GetCurrentProcess(), ADJUST_PRIV, Token) then<br>&nbsp; &nbsp; &nbsp; Error := Error or 4;<br>&nbsp; if not LookupPrivilegeValue(nil, SHTDWN_PRIV,TokenPriv.Privileges[0].Luid) then<br>&nbsp; &nbsp; Error := Error or 8;<br>&nbsp; TokenPriv.Privileges[0].Attributes := SE_PRIVILEGE_ENABLED;<br>&nbsp; TokenPriv.PrivilegeCount := 1; &nbsp;// One privilege to set<br>&nbsp; if not AdjustTokenPrivileges(Token, false, TokenPriv, PRIV_SIZE,Dummy, Len) then<br>&nbsp; &nbsp; Error:=Error or 16;<br>&nbsp; ExitWindowsEx(uFlags, 0);<br>&nbsp; Result := (Error=0);<br>end;<br><br><br>调用:<br>ShutDown(EWX_POWEROFF + EWX_FORCE);//强制关机并无任何提示<br><br><br>uFlags:<br>Specifies the type of shutdown. This parameter must be some combination of the following values: <br><br>Value Meaning<br>EWX_FORCE Forces processes to terminate. When this flag is set, Windows does not send the messages WM_QUERYENDSESSION and WM_ENDSESSION to the applications currently running in the system. This can cause the applications to lose data. Therefore, you should only use this flag in an emergency.<br>EWX_LOGOFF Shuts down all processes running in the security context of the process that called the ExitWindowsEx function. Then it logs the user off.<br>EWX_POWEROFF Shuts down the system and turns off the power. The system must support the power-off feature.Windows NT: The calling process must have the SE_SHUTDOWN_NAME privilege. For more information, see the following Remarks section. Windows 95: Security privileges are not supported or required.<br>EWX_REBOOT Shuts down the system and then restarts the system. Windows NT: The calling process must have the SE_SHUTDOWN_NAME privilege. For more information, see the following Remarks section. Windows 95: Security privileges are not supported or required.<br>EWX_SHUTDOWN Shuts down the system to a point at which it is safe to turn off the power. All file buffers have been flushed to disk, and all running processes have stopped. Windows NT: The calling process must have the SE_SHUTDOWN_NAME privilege. For more information, see the following Remarks section. Windows 95: Security privileges are not supported or required.<br><br>
 
WIN2000 SERVER 是不支持软件关机的.<br>WIN2000 PROFESSINOL 是一定可以的.我用VC 搞过一个,核心思想与HUJUNYI的一样.WINNT/2000<br>实现此类功能涉及程序权限的问题!
 
WIN2000 在一些新的主板上要改设置才能软关机<br><br>控制面板-&gt;电源管理<br>
 
前面的代码我在W2K中文版,D4,HP VEI8-PIII650机上测试通过。<br>不防需要都试一下啦。
 
太好了。看了 hujunyi 的代码。我才发现我的问题原来出现在 ExitWindowsEx 函数的参数<br>上。我只给了EWX_POWEROFF,没有加 EWX_FORCE,想 hujunyi 那样加上两个参数我就可以<br>软件关机后自动关闭电源了。cactus123456说的也是对的。只是我对他的程序没有好好<br>分析。我给你俩都加25分吧。谢谢了。
 
后退
顶部