線上訂房服務-台灣趴趴狗聯合訂房中心
發文 回覆 瀏覽次數:3149
推到 Plurk!
推到 Facebook!

請問如何讓 Windows 2003 強制 reboot (Delphi 2009)

答題得分者是:小傑克
pcboy
版主


發表:177
回覆:1838
積分:1463
註冊:2004-01-13

發送簡訊給我
#1 引用回覆 回覆 發表時間:2009-04-01 11:13:05 IP:61.220.xxx.xxx 訂閱
 請問如何讓 Windows 2003 強制 reboot
( 要放在系統排程, 每天自動執行)
下面是參考舊文章的程式, 但是測試無效, 請問哪裡要修改 ? 謝謝
http://delphi.ktop.com.tw/board.php?cid=30&fid=72&tid=95408

[code delphi]
// Delphi 2009 Atchitect
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs;
type
TForm1 = class(TForm)
procedure FormCreate(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
var
Form1: TForm1;
implementation
{$R *.dfm}
// 參考 http://delphi.ktop.com.tw/board.php?cid=30&fid=72&tid=95408
function ExitWindows(RebootParam: Longword): Boolean;
var
TTokenHd: THandle;
TTokenPvg: TTokenPrivileges;
cbtpPrevious: DWORD;
rTTokenPvg: TTokenPrivileges;
pcbtpPreviousRequired: DWORD;
tpResult: Boolean;
const
SE_SHUTDOWN_NAME = 'SeShutdownPrivilege';
begin
if Win32Platform = VER_PLATFORM_WIN32_NT then
begin
tpResult := OpenProcessToken(GetCurrentProcess(),
TOKEN_ADJUST_PRIVILEGES or TOKEN_QUERY,
TTokenHd);
if tpResult then
begin
tpResult := LookupPrivilegeValue(nil,
SE_SHUTDOWN_NAME,
TTokenPvg.Privileges[0].Luid);
TTokenPvg.PrivilegeCount := 1;
TTokenPvg.Privileges[0].Attributes := SE_PRIVILEGE_ENABLED;
cbtpPrevious := SizeOf(rTTokenPvg);
pcbtpPreviousRequired := 0;
if tpResult then
Windows.AdjustTokenPrivileges(TTokenHd,
False,
TTokenPvg,
cbtpPrevious,
rTTokenPvg,
pcbtpPreviousRequired);
end;
end;
Result := ExitWindowsEx(RebootParam, 0);
end;
// 下面八個動作中任選一種執行 ....
// 一般關閉,關閉前會詢問其它執行中的程式是否存檔
//ExitWindowsEx(EWX_LOGOFF,0); // 登出, 重新登入使用者
//ExitWindowsEx(EWX_REBOOT,0); // 重新開機
//ExitWindowsEx(EWX_SHUTDOWN,0); // 結束作業系統,出現"您可以放心關機畫面"
//ExitWindowsEx(EWX_POWEROFF,0); // 結束作業系統,並關閉電源(僅支援ATX 規格)
// 強制關閉,其它執行中的應用程式資料並不會被儲存
//ExitWindowsEx(EWX_LOGOFF | EWX_FORCE,0); // 登出, 重新登入使用者
//ExitWindowsEx(EWX_REBOOT | EWX_FORCE,0); // 重新開機
//ExitWindowsEx(EWX_SHUTDOWN | EWX_FORCE,0); // 結束作業系統
//ExitWindowsEx(EWX_POWEROFF | EWX_FORCE,0); // 結束作業系統,並關閉電源
// http://delphi.ktop.com.tw/board.php?cid=30&fid=72&tid=95408
procedure TForm1.FormCreate(Sender: TObject);
begin
ExitWindowsEx(EWX_REBOOT or EWX_FORCE,0); // 重新開機 , 無效果
end;

end.
[/code]
------
能力不足,求助於人;有能力時,幫幫別人;如果您滿意答覆,請適時結案!

子曰:問有三種,不懂則問,雖懂有疑則問,雖懂而想知更多則問!
編輯記錄
pcboy 重新編輯於 2009-04-01 11:13:32, 註解 無‧
小傑克
資深會員


發表:5
回覆:209
積分:357
註冊:2009-02-16

發送簡訊給我
#2 引用回覆 回覆 發表時間:2009-04-01 16:17:47 IP:59.112.xxx.xxx 訂閱
可以用簡單一點的方法, 產出一個bat檔,執行cmd 
shutdown /s /f /t 1
詳細說明參考shutdown /?
reboot 用 /r
------
額有朝天骨,眼中有靈光
編輯記錄
小傑克 重新編輯於 2009-04-01 16:19:18, 註解 無‧
小傑克 重新編輯於 2009-04-01 16:32:59, 註解 無‧
pcboy
版主


發表:177
回覆:1838
積分:1463
註冊:2004-01-13

發送簡訊給我
#3 引用回覆 回覆 發表時間:2009-04-01 17:09:10 IP:61.220.xxx.xxx 訂閱
小弟目前是用 bat , 掛在排程, 裡面寫
shutdown /r /f /t 0

不過小弟想知道程式如何寫
------
能力不足,求助於人;有能力時,幫幫別人;如果您滿意答覆,請適時結案!

子曰:問有三種,不懂則問,雖懂有疑則問,雖懂而想知更多則問!
小傑克
資深會員


發表:5
回覆:209
積分:357
註冊:2009-02-16

發送簡訊給我
#4 引用回覆 回覆 發表時間:2009-04-01 20:39:29 IP:59.112.xxx.xxx 訂閱
程式這樣可以,我在2003上測ok

ExitWindowsEx(EWX_REBOOT and EWX_FORCE,0); // 是and 不是or
------
額有朝天骨,眼中有靈光
編輯記錄
小傑克 重新編輯於 2009-04-01 20:40:37, 註解 無‧
pcboy
版主


發表:177
回覆:1838
積分:1463
註冊:2004-01-13

發送簡訊給我
#5 引用回覆 回覆 發表時間:2009-04-02 11:15:43 IP:61.220.xxx.xxx 訂閱
小弟在 Windows XP  PRO 和 Windows 2003 Std R2 上測試都只會 登出 ( logout ), 不會 reboot

===================引 用 小傑克 文 章===================
程式這樣可以,我在2003上測ok

ExitWindowsEx(EWX_REBOOT and EWX_FORCE,0); // 是and 不是or
------
能力不足,求助於人;有能力時,幫幫別人;如果您滿意答覆,請適時結案!

子曰:問有三種,不懂則問,雖懂有疑則問,雖懂而想知更多則問!
小傑克
資深會員


發表:5
回覆:209
積分:357
註冊:2009-02-16

發送簡訊給我
#6 引用回覆 回覆 發表時間:2009-04-02 14:21:18 IP:59.112.xxx.xxx 訂閱
根據msdn說明, 如果要poweroff, reboot 要先取得權限   AdjustTokenPrivileges ,根據這個我找到以前有人寫好的sample,這個確定可以
http://msdn.microsoft.com/en-us/library/aa376868(VS.85).aspx

[code delphi]
procedure TForm1.FormCreate(Sender: TObject);
var
VerInfo: TOSVersionInfo;
hToken: THANDLE;
tkp: TOKEN_PRIVILEGES;
Nothing: Cardinal;
begin
VerInfo.dwOSVersionInfoSize := SizeOf(VerInfo);
GetVersionEx(VerInfo);
if VerInfo.dwPlatformId = VER_PLATFORM_WIN32_NT then
begin
OpenProcessToken(GetCurrentProcess,TOKEN_ADJUST_PRIVILEGES or TOKEN_QUERY, hToken);
LookupPrivilegeValue(nil, 'SeShutdownPrivilege', tkp.Privileges[0].Luid);
tkp.PrivilegeCount := 1;
tkp.Privileges[0].Attributes := SE_PRIVILEGE_ENABLED;
AdjustTokenPrivileges(hToken, FALSE, tkp, 0, nil, Nothing);
end;
ExitWindowsEx(EWX_REBOOT, 0);
end;

[/code]
------
額有朝天骨,眼中有靈光
P.D.
版主


發表:603
回覆:4038
積分:3874
註冊:2006-10-31

發送簡訊給我
#7 引用回覆 回覆 發表時間:2009-04-07 11:24:25 IP:61.67.xxx.xxx 未訂閱

[code delphi]

// XP下配合關機時的權限釋放程式
procedure AdjustToken;
var hdlProcessHandle: Cardinal;
hdlTokenHandle: Cardinal;
tmpLuid: Int64;
// tkpPrivilegeCount: Int64;
tkp: TOKEN_PRIVILEGES;
tkpNewButIgnored: TOKEN_PRIVILEGES;
lBufferNeeded: Cardinal;
Privilege: array[0..0] of _LUID_AND_ATTRIBUTES;
begin
hdlProcessHandle:= GetCurrentProcess;
OpenProcessToken(hdlProcessHandle,(TOKEN_ADJUST_PRIVILEGES Or TOKEN_QUERY),
hdlTokenHandle);
// Get the LUID for shutdown privilege.
LookupPrivilegeValue('', 'SeShutdownPrivilege', tmpLuid);
Privilege[0].Luid:= tmpLuid;
Privilege[0].Attributes:= SE_PRIVILEGE_ENABLED;
tkp.PrivilegeCount:= 1; // One privilege to set
tkp.Privileges[0]:= Privilege[0];
// Enable the shutdown privilege in the access token of this
// process.
AdjustTokenPrivileges(hdlTokenHandle,False,tkp,Sizeof(tkpNewButIgnored),
tkpNewButIgnored,lBufferNeeded);
end;

實際call程式如下: 這是我現在正在使用, 在xp, 2003, 2000以下都ok, vista 沒有測過
case rgBoot.ItemIndex of
0: begin // 關機
AdjustToken;
ExitWindowsEX(EWX_FORCE OR EWX_SHUTDOWN ,0);
end;
1: begin // 重開
AdjustToken;
ExitWindowsEX(EWX_FORCE OR EWX_REBOOT ,0);
end;
else Hide;

[/code]
編輯記錄
P.D. 重新編輯於 2009-04-07 11:25:57, 註解 無‧
pcboy
版主


發表:177
回覆:1838
積分:1463
註冊:2004-01-13

發送簡訊給我
#8 引用回覆 回覆 發表時間:2009-04-07 12:06:02 IP:61.220.xxx.xxx 訂閱
測試確認在 Windows 2003 下可用, 感謝

===================引 用 小傑克 文 章===================
根據msdn說明, 如果要poweroff, reboot 要先取得權限 AdjustTokenPrivileges ,根據這個我找到以前有人寫好的sample,這個確定可以
http://msdn.microsoft.com/en-us/library/aa376868(VS.85).aspx

[code delphi]
procedure TForm1.FormCreate(Sender: TObject);
var
VerInfo: TOSVersionInfo;
hToken: THANDLE;
tkp: TOKEN_PRIVILEGES;
Nothing: Cardinal;
begin
VerInfo.dwOSVersionInfoSize := SizeOf(VerInfo);
GetVersionEx(VerInfo);
if VerInfo.dwPlatformId = VER_PLATFORM_WIN32_NT then
begin
OpenProcessToken(GetCurrentProcess,TOKEN_ADJUST_PRIVILEGES or TOKEN_QUERY, hToken);
LookupPrivilegeValue(nil, 'SeShutdownPrivilege', tkp.Privileges[0].Luid);
tkp.PrivilegeCount := 1;
tkp.Privileges[0].Attributes := SE_PRIVILEGE_ENABLED;
AdjustTokenPrivileges(hToken, FALSE, tkp, 0, nil, Nothing);
end;
ExitWindowsEx(EWX_REBOOT, 0);
end;

[/code]
------
能力不足,求助於人;有能力時,幫幫別人;如果您滿意答覆,請適時結案!

子曰:問有三種,不懂則問,雖懂有疑則問,雖懂而想知更多則問!
系統時間:2024-04-20 0:52:35
聯絡我們 | Delphi K.Top討論版
本站聲明
1. 本論壇為無營利行為之開放平台,所有文章都是由網友自行張貼,如牽涉到法律糾紛一切與本站無關。
2. 假如網友發表之內容涉及侵權,而損及您的利益,請立即通知版主刪除。
3. 請勿批評中華民國元首及政府或批評各政黨,是藍是綠本站無權干涉,但這裡不是政治性論壇!