Background Note:
Some time ago, I developed a data conversion system. The business logic stated that the data needed to be compressed into .tar.gz format.
I use it under Windows system. I first generate a batch file, then call WinExec to execute the batch file, sleep and wait for a period of time to complete the automatic compression of data.
Later, it was discovered that the size of the file to be compressed was uncertain, and simply sleeping for a fixed time when executing WinExec may cause compression failure, incomplete files or damage.
Optimization plan:
Instead of WinExe, use CreateProcess to start the process and execute the batch file. At the same time, the system will automatically fill in the TProcessInformation structure.
At this time, the program will automatically block in the batch, waiting for the process of the batch handle to end or timeout. This will resolve the compression damage issue.
Give an example Demo:
The D7 code is as follows:
unit uMain;interfaceuses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, RzButton, StdCtrls;type TFrmMain = class(TForm) mmMsg: TMemo; btnExecute: TRzBitBtn; btnClear: TRzBitBtn; procedure MsgDsp(v_Str: string); procedure btnExecuteClick(Sender: TObject); procedure btnClearClick(Sender: TObject); private { Private declarations } public { Public declarations } end;var FrmMain: TFrmMain;implementation{$R *.dfm}procedure TFrmMain.MsgDsp(v_Str: string); begin mmMsg.Lines.Add('[ admin ] - [' + v_Str + '] - [' + FormatDateTime('YYYY-MM-DD hh:mm:ss zzz', Now()) + ']');end;procedure TFrmMain.btnExecuteClick(Sender: TObject);var sInfo: TStartupInfo ; pInfo: TProcessInformation; cmdLine: string; exitCode: Cardinal;begin MsgDsp('Initialization parameters'); cmdLine := 'C:/Program Files/7-Zip/7zFM.exe'; FillChar(sInfo, sizeof(sInfo), #0); sInfo.cb := SizeOf(sInfo); sInfo.dwFlags := STARTF_USESHOWWINDOW; sInfo.wShowWindow := SW_NORMAL; MsgDsp('Parameter initialization is completed, start WinExec debugging'); //CreateProcess is used to start the process. After the process is started, the TProcessInformation structure will be filled in. //At this time, the program blocks into the handle, waiting for the handle's process to end or timeout if not CreateProcess(nil, pchar(cmdLine), nil, nil, false, CREATE_NEW_CONSOLE or NORMAL_PRIORITY_CLASS, nil, nil, sInfo, pInfo) then begin MsgDsp('WinExec debugging failed! '); MessageBox(Application.handle, 'The specified program failed to start!', 'Error', MB_OK or MB_ICONSTOP); end else begin //Wait for the process of the specified handle to end or timeout WaitForSingleObject(pInfo.hProcess, INFINITE); GetExitCodeProcess( pInfo.hProcess, exitCode); MsgDsp('WinExec debugging successful!'); end;end;procedure TFrmMain.btnClearClick(Sender: TObject);begin mmMsg.Clear;end;end.
The running effect is as follows:
Summarize
The above is the editor's introduction to Delphi calling external programs and blocking into external programs. I hope it will be helpful to you. If you have any questions, please leave me a message and the editor will reply to you in time. I would also like to thank everyone for your support of the Wulin.com website!
If you think this article is helpful to you, you are welcome to reprint it, please indicate the source, thank you!