win2000 服务问题。(100分)

  • 主题发起人 主题发起人 kingdeezj
  • 开始时间 开始时间
K

kingdeezj

Unregistered / Unconfirmed
GUEST, unregistred user!
SYSTEM: WIN2000 Family server
近接手一项目,其中有一项功能需要在计算机关机时执行。我拦截了WM_QUERYENDSESSION
消息,但是在调用外部EXE文件的时候提示:“因窗口站关闭,应用程序初始化失败。”
有可能是win2000在接受用户关机命令时不等WM_QUERYENDSESSION返回信息就结束服务造成。
请教各位在WM_QUERYENDSESSION之前,win2000又根据的何种消息结束服务?
 
换句话说就是WIN2000在结束掉其他进程后,我的程序才收到WM_QUERYENDSESSION消息.
(呵呵,好像是这样的)
 
首先要了解Windows的关机的程序。当用户退出Windows时,Windows系统会给每个Top-level的
窗体发WM_QUERYENDSESSION 的系统消息,查询能否关机,窗体可在接到此消息时进行结束前的工作
(如编辑类的窗体会提示未保存的文件存盘等),窗体返回TRUE为同意关机,FALSE为不同意关机。
Windows9x等所有的窗体都回应了WM_QUERYENDSESSION后,系统会再发WM_ENDSESSION的消息,消息的
wparam 参数为是否结束Windows,若TRUE,窗体要马上结束程序,若FALSE则取消关闭Windows的命令,
窗体可以照常工作。只要某一窗体在WM_QUERYENDSESSION返回FALSE(不同意关机),WM_ENDSESSION的
wparam即为FALSE。
而在Windows NT/2000窗体返回WM_QUERYENDSESSION后马上接到WM_ENDSESSION的消息,不用等其它
窗体对WM_QUERYENDSESSION的回应。不管在9x、Nt和2000,各Top-level的窗体都可以“一票否决”取消
关闭Windows的命令,这样可以确保应用程序的数据不会丢失。

自己的程序可以捕捉上述的两个消息.

procedure WMQueryEndSession (var Message: TMessage); message WM_QUERYENDSESSION ;
如果返回0,表明不能关闭
 
通过查找资料,看到这样一句:
WINDOWS系统不允许在带参数为TRUE的WM_QueryEndSession系统消息调用外部程序。
唉。。。只好在拦截WM_QueryEndSession消息时先让它返回FALSE;
现在可以调用EXE了,可用户得两次选择关机。
真是鱼与熊掌不可兼得。
哪位大侠能出出主意?
 
俺有一段程序可以关闭2000,不过没试验过,txyqbf_gxx@163.com
 
当然也能拦截
 
to 人在昆明:
谢谢你的关注。你能把这段程序发给我借鉴一下么?
E-Mail: Kingdeezj@sina.com
 
俺有一段Win2000关机的代码,而且试过绝对可行。只是它是VB做的,
俺没时间翻译,要不?不过试过之后,俺发现一个小问题:就是Win2000
用这种方法关掉之后,竟然会出现:你现在可以安全地关机了!!!
好像之前这个东东只在Win98里见到。不知咋的。
 
to BigBing:(WIN2000关机)
function TForm1.SetPrivilege(sPrivilegeName: string;
bEnabled: Boolean): Boolean;

var
TPPrev,
TP : TTokenPrivileges;
Token :THandle;
dwRetLen : DWORD;
begin
result := False;
OpenProcessToken (GetCurrentProcess,
TOKEN_ADJUST_PRIVILEGES or TOKEN_QUERY,
Token);
TP.PrivilegeCount := 1;
if LookupPrivilegeValue (nil, PChar (sPrivilegeName), TP.Privileges[0].LUID) then
begin
if bEnabled then
TP.Privileges[0].Attributes := SE_PRIVILEGE_ENABLED
else
TP.Privileges[0].Attributes := 0;
dwRetLen := 0;
result := AdjustTokenPrivileges (
Token,
False,
TP,
SizeOf (TPPrev),
TPPrev,
dwRetLen);
end;
CloseHandle (Token);
end;
function Tform1.WinExit (iFlags: integer) : Boolean;

begin
result := true;
if SetPrivilege ('SeShutdownPrivilege', true) then
begin
if (not ExitWindowsEx (iFlags, 0)) then
begin
// handle errors...
result := False
end;
SetPrivilege ('SeShutdownPrivilege', False)
end
else
begin
// handle errors...
result := False
end;
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
WinExit(EWX_POWEROFF + EWX_FORCE);
end;
 
再次寻求答案。
 
有没有办法隐藏W2k关机时那个“请稍后。。。”窗口?
 
这一段程序我调试通过了的你看一下是否能帮你,分都无所谓共同进步嘛
unit mainunit;

interface

uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls;

type
TForm1 = class(TForm)
Label1: TLabel;
GroupBox1: TGroupBox;
Button1: TButton;
Button2: TButton;
RadioButton1: TRadioButton;
RadioButton2: TRadioButton;
RadioButton3: TRadioButton;
RadioButton4: TRadioButton;
procedure FormShow(Sender: TObject);
procedure FormCreate(Sender: TObject);
procedure Button2Click(Sender: TObject);
procedure Button1Click(Sender: TObject);
private
{ Private declarations }
public
function GetWinVer:Byte;
function SetPrivilege(PrivilegeName:string;Enable:Boolean):Boolean;
procedure ShutDownSystem(EWX_TYPE:Integer);
{ Public declarations }
end;

var
Form1: TForm1;

implementation

{$R *.dfm}
const
EWX_FORCE=4;
EWX_LOGOFF=0;
EWX_SHUTDOWN=1;
EWX_REBOOT=2;
EWX_POWEROFF=8;

{ TForm1 }

function TForm1.GetWinVer: Byte;
var
OS:TOSVersionInfo;
begin
OS.dwOSVersionInfoSize:=sizeof(tosversioninfo);
GetVersionEx(OS);
case OS.dwPlatformId of
VER_PLATFORM_WIN32s : Result:=0;
VER_PLATFORM_WIN32_WINDOWS : Result:=1;
VER_PLATFORM_WIN32_NT :Result:=2;
end;
end;

function TForm1.SetPrivilege(PrivilegeName: string;
Enable: Boolean): Boolean;
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;

procedure TForm1.ShutDownSystem(EWX_TYPE: Integer);
begin
if getwinver=2 then
begin
SetPrivilege('SeShutdownPrivilege',true);
if (not ExitWindowsEx(EWX_TYPE,0)) then
SetPrivilege('SeShutdownPrivilege',false);
end
else
ExitWindowsEx(EWX_TYPE,0);
end;

procedure TForm1.FormShow(Sender: TObject);
begin
RadioButton1.Checked:=true;
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
if getwinver=2 then
begin
Label1.Caption:=Label1.Caption+'Windows NT';
end
else
begin
Label1.Caption:=Label1.Caption+'Windows 95/98';
end;
end;

procedure TForm1.Button2Click(Sender: TObject);
begin
if Application.MessageBox('你是否决定执行本操作?','系统询问',
MB_OKCANCEL+MB_OK)=IDOK then
begin
if (RadioButton1.Checked) then
ShutDownSystem(EWX_SHUTDOWN)
else if (RadioButton2.Checked) then
ShutDownSystem(EWX_REBOOT)
else if (RadioButton3.Checked) then
ShutDownSystem(EWX_LOGOFF)
else if (RadioButton4.Checked) then
ShutDownSystem(EWX_POWEROFF);
end;
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
close;
end;

end.
 
楼主帮你顶顶,也借宝地一用:
http://www.delphibbs.com/delphibbs/dispq.asp?lid=2460751
 
请问你回复谁?
 
后退
顶部