如何等待进程结束?(100分)

  • 主题发起人 主题发起人 qj_chen
  • 开始时间 开始时间
Q

qj_chen

Unregistered / Unconfirmed
GUEST, unregistred user!
&nbsp; &nbsp;以下是一段执行外部程序--改变“控制面板”中的日期格式--的源代码(从大富翁<br>上搬来的)。如果改变了日期格式,一按“确定”就死机。请教专家,原因何在?我的要求<br>是等待进程结束,而不是改变日期的方法!!!<br>unit Unit1;<br><br>interface<br><br>uses<br>&nbsp; Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,<br>&nbsp; StdCtrls, WinProcs, ShellAPI;<br><br>type<br>&nbsp; TForm1 = class(TForm)<br>&nbsp; &nbsp; Button1: TButton;<br>&nbsp; &nbsp; procedure Button1Click(Sender: TObject);<br>&nbsp; &nbsp; <br>&nbsp; private<br>&nbsp; &nbsp; { Private declarations }<br>&nbsp; public<br>&nbsp; &nbsp; { Public declarations }<br>&nbsp; end;<br><br>var<br>&nbsp; Form1: TForm1;<br><br>implementation<br><br>{$R *.DFM}<br><br>procedure TForm1.Button1Click(Sender: TObject);<br>var <br>&nbsp; cmdStr:pchar; <br>&nbsp; StartupInfo: TStartupInfo;<br>&nbsp; ProcessInfo: TProcessInformation;<br>begin<br>&nbsp; cmdstr:=pchar('RunDLL32.exe Shell32.DLL,Control_RunDLL Intl.cpl,,4');<br>&nbsp; {建立进程并等待其结束}<br>&nbsp; fillchar(StartupInfo,sizeof(StartupInfo),0);<br>&nbsp; CreateProcess(nil,cmdstr,nil,nil,false,0,nil,nil,StartupInfo,ProcessInfo);<br>&nbsp; With ProcessInfo do<br>&nbsp; &nbsp; begin<br>&nbsp; &nbsp; &nbsp; CloseHandle(hThread);<br>&nbsp; &nbsp; &nbsp; WaitForSingleObject(hProcess, INFINITE);<br>&nbsp; &nbsp; &nbsp; CloseHandle(hProcess);<br>&nbsp; &nbsp; end;<br>end;<br><br>end.<br>
 
好像没什么问题,是这么写的
 
请您编译运行试试,一旦改变了日期格式就死机了!!!
 
要使用线程,我认为,你改变日期格式后,Windows会广播一条消息,<br>然后阻塞在你原来的主线程中了<br><br>&nbsp; TMyThread = class(TThread )<br>&nbsp; public<br>&nbsp; procedure Execute; override;<br>&nbsp; end;<br><br>&nbsp; TForm1 = class(TForm)<br>&nbsp; &nbsp; mythread:TMyThread;<br>&nbsp; &nbsp; Button1: TButton;<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; { Private declarations }<br>&nbsp; public<br>&nbsp; &nbsp; { Public declarations }<br>&nbsp; end;<br><br>var<br>&nbsp; Form1: TForm1;<br><br>
 
implementation<br><br>{$R *.DFM}<br><br>procedure TMyThread.Execute;<br>var cmdstr:pchar;<br>&nbsp; &nbsp; StartupInfo:TStartupInfo;<br>&nbsp; &nbsp; processinfo:TProcessInformation;<br>&nbsp; &nbsp; res:integer;<br>begin<br>&nbsp; &nbsp;cmdstr:=pchar('RunDLL32.exe Shell32.DLL,Control_RunDLL Intl.cpl,,4');<br>&nbsp; &nbsp;fillchar(StartupInfo,sizeof(StartupInfo),0);<br>&nbsp; &nbsp;CreateProcess(nil,cmdstr,nil,nil,false,0,nil,nil,StartupInfo,ProcessInfo);<br>&nbsp; &nbsp;CloseHandle( processinfo.hThread );<br>&nbsp; &nbsp;while not Terminated do<br>&nbsp; &nbsp;begin<br>&nbsp; &nbsp; &nbsp; &nbsp;res := WaitForSingleObject( processinfo.hprocess,1000 );<br>&nbsp; &nbsp; &nbsp; &nbsp;if res &lt;&gt; WAIT_TIMEOUT then<br>&nbsp; &nbsp; &nbsp; &nbsp;begin<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;closehandle( processinfo.hprocess );<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;exit;<br>&nbsp; &nbsp; &nbsp; &nbsp;end;<br>&nbsp; &nbsp;end;<br>end;<br>
 
procedure TForm1.Button1Click(Sender: TObject);<br>begin<br>&nbsp; &nbsp;mythread := TMyThread.Create(false);<br>end;<br><br>procedure TForm1.Button2Click(Sender: TObject);<br>begin<br>&nbsp; mythread.Terminate;<br>&nbsp; mythread.free;<br>end;<br><br>end.<br>
 
谢谢hustmouse,但是我的要求是等待该进程结束后再执行下一段代码,关键是等待!!!<br>Sorry,等待您的答案,再给您送分。100分。
 
咦,我的代码里面已经有了啊。<br><br>在TMyThread.Execute中<br><br>有WaitForSingleObject的那句,就是等待进程结束啊。<br><br>不过,你不使用线程也行,如以下代码(在主线程中)<br><br>var &nbsp;ahandles:array [0..0] of HANDLE;<br>&nbsp; &nbsp; &nbsp;res:integer;<br>&nbsp; &nbsp; &nbsp;finish:boolean;<br><br>CreateProcess(nil,cmdstr,nil,nil,false,0,nil,nil,StartupInfo,ProcessInfo);<br>ahandles[0] := &nbsp;processinfo.hprocess;<br>finish := false;<br>while not finish do<br>begin<br>res := MsgWaitForMultipleObjects( 1,ahandles,false,INFINITE,QS_POSTMESSAGE or <br>&nbsp; &nbsp;QS_SENDMESSAGE );<br>if res= &nbsp;WAIT_OBJECT_0 then<br>begin //进程结束<br>&nbsp;finish := true;<br>end<br>else if res = WAIT_OBJECT_0 + 1 then //有窗口消息要处理<br>begin<br>&nbsp; Application.Processmessage;<br>end;<br>end;
 
今天有空编译了一下。其实与我预计的一致,写法本身没有问题,关键是你调用的进程:<br>日期格式调整,在你按了确定之后,其实进程并不结束,是继续运行的,所以你的<br>WaitForSingleObject(hProcess, INFINITE);是一定要等到进程结束,所以表现自然像死机。<br>如果你用任务管理器将rundll32的进程真正kill,那你的程序就恢复正常了。<br>所以对于这个特定的任务(调整日期格式)来说,就不能用WaitForSingleObject(hProcess, INFINITE);<br>其实你可以自己写个循环检查调整日期格式窗口状态,一旦他隐藏,就表示用户已经结算了操作。<br>具体代码略。
 
谢谢hustmouse和daiqingbo!因为仅有100分,只能勉强分配,请见谅!!!
 
后退
顶部