Delphi - 调用外部程序并阻塞到外部程序中
Delphi 调用外部程序并阻塞到外部程序中
背景说明:
前段时间开发一个数据转换的系统,业务逻辑中说明数据需要压缩成.tar.gz格式。
我在Windows系统下采用,先生成批处理文件,然后调用WinExec执行批处理文件,休眠等待一段时间,完成数据的自动压缩。
后来发现,待压缩文件的大小不确定,单纯的执行WinExec时Sleep固定时间,可能导致压缩失败、文件不全或损坏。
优化方案:
取代WinExe用CreateProcess用来启动进程, 执行批处理文件, 同时系统会自动填写TProcessInformation这个结构。
此时程序会自动阻塞到该批处理中,等待批处理句柄的进程结束或超时。这样就能解决压缩损坏问题。
给个实例Demo:
D7代码如下:
unit uMain; interface uses
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('初始化参数');
cmdLine := 'C:\Program Files\7-Zip\7zFM.exe';
FillChar(sInfo, sizeof(sInfo), #);
sInfo.cb := SizeOf(sInfo);
sInfo.dwFlags := STARTF_USESHOWWINDOW;
sInfo.wShowWindow := SW_NORMAL;
MsgDsp('参数初始化完成,启动WinExec调试');
//CreateProcess用来启动进程, 进程启动后, 会填写TProcessInformation这个结构,
//此时程序阻塞到该句柄中,等待句柄的进程结束或超时
if not CreateProcess(nil, pchar(cmdLine), nil, nil, false, CREATE_NEW_CONSOLE or NORMAL_PRIORITY_CLASS, nil, nil, sInfo, pInfo) then
begin
MsgDsp('WinExec调试失败!');
MessageBox(Application.handle, '指定程序启动失败!', '错误', MB_OK or MB_ICONSTOP);
end
else
begin
//等待指定句柄的进程结束或超时
WaitForSingleObject(pInfo.hProcess, INFINITE);
GetExitCodeProcess(pInfo.hProcess, exitCode);
MsgDsp('WinExec调试成功!');
end;
end; procedure TFrmMain.btnClearClick(Sender: TObject);
begin
mmMsg.Clear;
end; end.
运行效果如下:

封装成函数如下:
//Jeremy.Wu
//2019.09.19
//https://www.cnblogs.com/jeremywucnblog/
function TFrmMain.GetCreateProcess(vCmdLine: string): Boolean;
var
sInfo: TStartupInfo;
pInfo: TProcessInformation;
exitCode: Cardinal;
begin
Result := False;
FillChar(sInfo, sizeof(sInfo), #);
sInfo.cb := SizeOf(sInfo);
sInfo.dwFlags := STARTF_USESHOWWINDOW;
sInfo.wShowWindow := SW_NORMAL;
//CreateProcess用来启动进程, 进程启动后, 会填写TProcessInformation这个结构,
//此时程序阻塞到该句柄中,等待句柄的进程结束或超时
if not CreateProcess(nil, pchar(vCmdLine), nil, nil, false, CREATE_NEW_CONSOLE or NORMAL_PRIORITY_CLASS, nil, nil, sInfo, pInfo) then
begin
Result := False;
end
else
begin
//等待指定句柄的进程结束或超时
WaitForSingleObject(pInfo.hProcess, INFINITE);
GetExitCodeProcess(pInfo.hProcess, exitCode);
Result := True;
end;
end;
作者:Jeremy.Wu
出处:https://www.cnblogs.com/jeremywucnblog/
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。
Delphi - 调用外部程序并阻塞到外部程序中的更多相关文章
- delphi调用外部程序打开文件
delphi调用外部程序打开文件 ShellExecute的各种用法 一.利用系统默认的邮件收发器发送电子邮件 Uses ..., ShellAPI; Var lpHwnd: HWND; lpOper ...
- Delphi 调用外部程序并等待其运行结束
转自:http://blog.csdn.net/xieyunc/article/details/4140620 如何让Delphi调用外部程序并等待其运行结束 1. uses Window ...
- 发现个delphi调用vc写的Dll中包括pchar參数报错奇怪现象
发现个delphi调用vc写的Dll中包括pchar參数奇怪现象 procedure中的第一行语句不能直接调用DLL的函数,否则会执行报错,在之前随意加上条语句就不报错了奇怪! vc的DLL源代码地址 ...
- Delphi调用DLL中的接口
问题描述: 具体问题就是在隐式使用接口变量后,在FreeLibrary执行后,就会出现一个非法访址的错误. 这个错误的原因就是在FreeLibrary后,DLL以的代码均为不可用状态,而在代码执行完整 ...
- delphi调用web service出现 Unable to retrieve the URL endpoint for Service/Port .....
delphi调用web service出现 Unable to retrieve the URL endpoint for Service/Port, 错误截图如下 查了很长时间, 发现在DataM ...
- 【转】Delphi调用webservice总结
原文:http://www.cnblogs.com/zhangzhifeng/archive/2013/08/15/3259084.html Delphi调用C#写的webservice 用delph ...
- Delphi 调用netsh命令修改IP地址
Delphi 调用netsh命令修改IP地址 先介绍一下Netsh命令的使用方法: 在这里跟大家介绍几个简单的指令 1.Show IP 1.1Cmd Mode 直接在cmd下面输入 netsh int ...
- 教程-Delphi调用C# WEBSERVICE(二)
第二步:将webserivce的WSDL导入到该dll工程中,如何导,方法至少有两种,我说简单的一种: file->new->other->WebService->WSDL ...
- [转]Delphi调用cmd的两种方法
delphi调用cmd的两种方法vars:string;begins:='cmd.exe /c '+edit1.Text+' >c:\1.txt';winexec(pchar(s),sw_hid ...
随机推荐
- 如何让textarea placeholder 文字垂直居中
<!DOCTYPE html><html lang="en"><head> <meta charset="UTF-8" ...
- S3C2440 移植最新5.2linux内核
基于 移植uboot后. 1. 移植linux内核 1.1 下载源码 打开 https://www.kernel.org/ 直接肝最新的 5.2.8 下载完后,在ubuntu里解压备用. 1.2 搭建 ...
- js及jquery常用代码
1.获取屏幕尺寸 document.documentElement.scrollWidth; document.documentElement.scrollHeight; $(window).widt ...
- .net core + mvc 手撸一个代码生成器
最近闲来无事,总想倒腾点什么,索性弄下代码生成器,这里感谢叶老板FreeSql的强大支持. 以前也用过两款不错的代码生成器,这里说说我的看法 1.动软代码生成器,优点很明显,免费,简单,但是没法高度自 ...
- JVM调优实战:G1中的to-space exhausted问题
最近刚刚将自己的一个应用从CMS升级到G1,在一天早上,刚刚到办公室坐下,就收到手机一阵报警,去查看了监控,发现机器的内存出现了一个90度的涨幅,如下图所示: 在查看GC日志后,发现那个时间点附近出现 ...
- 安排:《蚂蚁花呗1234面:Redis+分布式架构+MySQL+linux+红黑树》
前言: 大厂面试机会难得,为了提高面试通关率,建议朋友们在面试前先复盘自己的知识栈,依据掌握程度划分重要.优先级,系统地去学习!如果不准备充分就去参加面试,既会失去进入大厂的机会,更是对自己的不负责. ...
- Codeforces 1009G
题意略. 思路: 首先是贪心, 我们从前往后依次从小到大考虑放哪个字符, 重点是判断放了这个字符后, 对于剩下的后缀是否存在合法解. 考虑每个位置的允许放的字符集合只有2 ^ 6种, 我们预处理一个后 ...
- Leetcode Weekly Contest 152
退役老人现在连leetcode都不会做了 = = 今天早上做了leetcode第三题题目看错了,加上比赛中间还在调投稿的实验,一心二用直接gg 总结下教训就是 本渣现在做题连题目都看不清就开始做.开始 ...
- Mac添加中国法定节假日安排
最近中秋.国庆临近,当大家开始抢票才反应过来,原来假日已然临近,打开mac日历,发现并没有标注节假日安排,发现了这篇文章,写了这篇读后感. 上面的文章介绍使用了两种在苹果系列设备设置中国节假日的方式: ...
- [企业微信通知系列]Jenkins发布后自动通知
一.前言 最近使用Jenkins进行自动化部署,但是部署后,并没有相应的通知,虽然有邮件发送通知,但是发现邮件会受限于接收方的接收设置,导致不能及时看到相关的发布内容.而由于公司使用的是企业微信,因此 ...