从我的程序中执行另外一个程序?(50分)

  • 主题发起人 主题发起人 sntmpl
  • 开始时间 开始时间
S

sntmpl

Unregistered / Unconfirmed
GUEST, unregistred user!
我用了SHELLEXECUTE从我的程序A中执行另外程序B,可B程序执行较慢,我想在B没显示出来前让A程序中的BUTTON1为不可用,等B显示出来后A的BUTTON1才可用,有什么办法???
 
用CreateProcess执行程序B<br>可以用WaitForInputIdle等待
 
WaitForSingleObject
 
能说的详细一点吗?
 
我也想知道!
 
我用了一个进程的方式,基本达到了上面的要求,但发现了一个问题:<br>A调用B,如果B不关闭,则A的窗体为一片白(不可用,什么都没有了),如何解决???
 
你用WaitForSingleObject等待的吧,这是等待进程结束,不对<br>应该用WaitForInputIdle
 
干脆按下后置button为disenable,延时几秒后估计可能弹出b程序在enable[:D],蠢办法
 
uses Forms, Windows;<br><br>procedure TForm1.Button1Click(Sender: TObject);<br>var<br>&nbsp; proc_info: TProcessInformation;<br>&nbsp; startinfo: TStartupInfo;<br>&nbsp; ExitCode: longword;<br>begin<br>&nbsp; // Initialize the structures<br>&nbsp; FillChar(proc_info, sizeof(TProcessInformation), 0);<br>&nbsp; FillChar(startinfo, sizeof(TStartupInfo), 0);<br>&nbsp; startinfo.cb := sizeof(TStartupInfo);<br><br>&nbsp; // Attempts to create the process<br>&nbsp; if CreateProcess('c:/windows/notepad.exe', nil, nil,<br>&nbsp; &nbsp; &nbsp; nil, false, NORMAL_PRIORITY_CLASS, nil, nil,<br>&nbsp; &nbsp; &nbsp; &nbsp;startinfo, proc_info) &lt;&gt; False then begin<br>&nbsp; &nbsp; // The process has been successfully created<br>&nbsp; &nbsp; // No let's wait till it ends...<br>&nbsp; &nbsp; WaitForSingleObject(proc_info.hProcess, INFINITE);<br>&nbsp; &nbsp; // Process has finished. Now we should close it.<br>&nbsp; &nbsp; GetExitCodeProcess(proc_info.hProcess, ExitCode); &nbsp;// Optional<br>&nbsp; &nbsp; CloseHandle(proc_info.hThread);<br>&nbsp; &nbsp; CloseHandle(proc_info.hProcess);<br>&nbsp; &nbsp; Application.MessageBox(<br>&nbsp; &nbsp; &nbsp; PChar(Format('Notepad finished! (Exit code=%d)', [ExitCode])),<br>&nbsp; &nbsp; &nbsp; 'Info', MB_ICONINFORMATION);<br>&nbsp; end else begin<br>&nbsp; &nbsp; // Failure creating the process<br>&nbsp; &nbsp; Application.MessageBox('Couldn''t execute the '<br>&nbsp; &nbsp; &nbsp; + 'application', 'Error', MB_ICONEXCLAMATION);<br>&nbsp; end;//if<br>end;<br>Problems<br><br>We have experienced problems with WaitForSingleObject in combination with certain applications and we had to finish them with the task manager. Other applications apparently fail to finish correctly and WaitForSingleObject never returns. Appart from that, an application does not respond to events while it waits and this means that for example the forms won't repaint...<br><br>A possible workaround to these problems is checking the status of the launched application (calling GetExitCodeProcess) at intervals (in a timer event).<br><br>uses Forms, Windows, StdCtrls, ExtCtrls;<br><br>type<br>TForm1 = class(TForm)<br>&nbsp; btnExecute: TButton;<br>&nbsp; btnCancel: TButton;<br>&nbsp; Timer1: TTimer;<br>&nbsp; procedure FormCreate(Sender: TObject);<br>&nbsp; procedure btnExecuteClick(Sender: TObject);<br>&nbsp; procedure Timer1Timer(Sender: TObject);<br>&nbsp; procedure btnCancelClick(Sender: TObject);<br>&nbsp; procedure FormCloseQuery(Sender: TObject;<br>&nbsp; &nbsp; var CanClose: Boolean);<br>private<br>&nbsp; proc_info: TProcessInformation;<br>&nbsp; startinfo: TStartupInfo;<br>&nbsp; ExitCode: LongWord;<br>end;<br><br>implementation<br><br>procedure TForm1.FormCreate(Sender: TObject);<br>begin<br>&nbsp; btnCancel.Enabled := False;<br>&nbsp; Timer1.Enabled := False;<br>&nbsp; Timer1.Interval := 200;<br>end;<br><br>procedure TForm1.btnExecuteClick(Sender: TObject);<br>begin<br>&nbsp; FillChar(proc_info, sizeof(TProcessInformation), 0);<br>&nbsp; FillChar(startinfo, sizeof(TStartupInfo), 0);<br>&nbsp; startinfo.cb := sizeof(TStartupInfo);<br>&nbsp; if CreateProcess(nil, 'c:/windows/notepad.exe', nil,<br>&nbsp; &nbsp; &nbsp; nil, false, CREATE_DEFAULT_ERROR_MODE<br>&nbsp; &nbsp; &nbsp; + NORMAL_PRIORITY_CLASS, nil, nil, startinfo,<br>&nbsp; &nbsp; &nbsp; proc_info) then begin<br>&nbsp; &nbsp; btnExecute.Enabled := False;<br>&nbsp; &nbsp; btnCancel.Enabled := True;<br>&nbsp; &nbsp; Timer1.Enabled := True;<br>&nbsp; end else begin<br>&nbsp; &nbsp; CloseHandle(proc_info.hProcess);<br>&nbsp; &nbsp; Application.MessageBox('Couldn''t execute the '<br>&nbsp; &nbsp; &nbsp; + 'application', 'Error', MB_ICONEXCLAMATION);<br>&nbsp; end;<br>end;<br><br>procedure TForm1.Timer1Timer(Sender: TObject);<br>begin<br>&nbsp; Timer1.Enabled := False;<br>&nbsp; if GetExitCodeProcess(proc_info.hProcess, ExitCode)<br>&nbsp; then<br>&nbsp; &nbsp; if ExitCode = STILL_ACTIVE then<br>&nbsp; &nbsp; &nbsp; Timer1.Enabled := True<br>&nbsp; &nbsp; else begin<br>&nbsp; &nbsp; &nbsp; btnCancel.Enabled := False;<br>&nbsp; &nbsp; &nbsp; btnExecute.Enabled := True;<br>&nbsp; &nbsp; &nbsp; CloseHandle(proc_info.hProcess);<br>&nbsp; &nbsp; end<br>&nbsp; else begin<br>&nbsp; &nbsp; btnCancel.Enabled := False;<br>&nbsp; &nbsp; btnExecute.Enabled := True;<br>&nbsp; &nbsp; TerminateProcess(proc_info.hProcess, 0);<br>&nbsp; &nbsp; CloseHandle(proc_info.hProcess);<br>&nbsp; end;<br>end;<br><br>procedure TForm1.btnCancelClick(Sender: TObject);<br>begin<br>&nbsp; Timer1.Enabled := False;<br>&nbsp; if Application.MessageBox('You should try to finish'<br>&nbsp; + ' the application normally.'#13#13'&amp;iquest;Terminate it '<br>&nbsp; + 'anyway?', 'Warning', MB_YESNO + MB_DEFBUTTON2 +<br>&nbsp; MB_ICONQUESTION + MB_TASKMODAL) = ID_YES then begin<br>&nbsp; &nbsp; TerminateProcess(proc_info.hProcess, 0);<br>&nbsp; &nbsp; CloseHandle(proc_info.hProcess);<br>&nbsp; &nbsp; btnCancel.Enabled := False;<br>&nbsp; &nbsp; btnExecute.Enabled := True;<br>&nbsp; end else begin<br>&nbsp; &nbsp; Timer1.Enabled := True;<br>&nbsp; end;<br>end;<br><br>procedure TForm1.FormCloseQuery(Sender: TObject;<br>&nbsp; var CanClose: Boolean);<br>begin<br>&nbsp; if btnCancel.Enabled then begin<br>&nbsp; &nbsp; btnCancelClick(Sender);<br>&nbsp; &nbsp; if btnCancel.Enabled then CanClose := False;<br>&nbsp; end;<br>end;<br>
 
多人接受答案了。
 
后退
顶部