Delphi calls external programs and blocks them into external programs
Background note:
Some time ago, a data conversion system was developed. The business logic stated that the data needed to be compressed into. tar.gz format.
I use Windows system, Mr. batch file processing, and then call WinExec to execute batch file, sleep and wait for a period of time, complete the automatic compression of data.
Later, it was found that the size of the file to be compressed is uncertain. Sleep fixed time when WinExec is executed alone may lead to compression failure, incomplete files or damage.
Optimizing scheme:
Instead of WinExe, CreateProcess is used to start processes, execute batch files, and the system automatically fills in the TProcess Information structure.
At this point, the program will automatically block into the batch, waiting for the end of the batch handle process or timeout. This can solve the problem of compression damage.
Give me an example Demo:
The D7 code is as follows:
1 unit uMain; 2 3 interface 4 5 uses 6 Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, 7 Dialogs, RzButton, StdCtrls; 8 9 type 10 TFrmMain = class(TForm) 11 mmMsg: TMemo; 12 btnExecute: TRzBitBtn; 13 btnClear: TRzBitBtn; 14 procedure MsgDsp(v_Str: string); 15 procedure btnExecuteClick(Sender: TObject); 16 procedure btnClearClick(Sender: TObject); 17 private 18 { Private declarations } 19 public 20 { Public declarations } 21 end; 22 23 var 24 FrmMain: TFrmMain; 25 26 implementation 27 28 {$R *.dfm} 29 30 procedure TFrmMain.MsgDsp(v_Str: string); 31 begin 32 mmMsg.Lines.Add('[ admin ] - [' + v_Str + '] - [' + FormatDateTime('YYYY-MM-DD hh:mm:ss zzz', Now()) + ']'); 33 end; 34 35 procedure TFrmMain.btnExecuteClick(Sender: TObject); 36 var 37 sInfo: TStartupInfo; 38 pInfo: TProcessInformation; 39 cmdLine: string; 40 exitCode: Cardinal; 41 begin 42 MsgDsp('Initialization parameters'); 43 cmdLine := 'C:\Program Files\7-Zip\7zFM.exe'; 44 FillChar(sInfo, sizeof(sInfo), #0); 45 sInfo.cb := SizeOf(sInfo); 46 sInfo.dwFlags := STARTF_USESHOWWINDOW; 47 sInfo.wShowWindow := SW_NORMAL; 48 MsgDsp('Parameter initialization completed, start WinExec debugging'); 49 //CreateProcess Used to start a process, After the process starts, Will fill in TProcessInformation This structure, 50 //At this point, the program blocks into the handle, waiting for the end of the process or timeout of the handle 51 if not CreateProcess(nil, pchar(cmdLine), nil, nil, false, CREATE_NEW_CONSOLE or NORMAL_PRIORITY_CLASS, nil, nil, sInfo, pInfo) then 52 begin 53 MsgDsp('WinExec Debugging failed!'); 54 MessageBox(Application.handle, 'Designated program failed to start!', 'error', MB_OK or MB_ICONSTOP); 55 end 56 else 57 begin 58 //Waiting for process termination or timeout of the specified handle 59 WaitForSingleObject(pInfo.hProcess, INFINITE); 60 GetExitCodeProcess(pInfo.hProcess, exitCode); 61 MsgDsp('WinExec Successful debugging!'); 62 end; 63 end; 64 65 procedure TFrmMain.btnClearClick(Sender: TObject); 66 begin 67 mmMsg.Clear; 68 end; 69 70 end.
The operation results are as follows: