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 - 调用外部程序并阻塞到外部程序中的更多相关文章

  1. delphi调用外部程序打开文件

    delphi调用外部程序打开文件 ShellExecute的各种用法 一.利用系统默认的邮件收发器发送电子邮件 Uses ..., ShellAPI; Var lpHwnd: HWND; lpOper ...

  2. Delphi 调用外部程序并等待其运行结束

    转自:http://blog.csdn.net/xieyunc/article/details/4140620   如何让Delphi调用外部程序并等待其运行结束 1. uses     Window ...

  3. 发现个delphi调用vc写的Dll中包括pchar參数报错奇怪现象

    发现个delphi调用vc写的Dll中包括pchar參数奇怪现象 procedure中的第一行语句不能直接调用DLL的函数,否则会执行报错,在之前随意加上条语句就不报错了奇怪! vc的DLL源代码地址 ...

  4. Delphi调用DLL中的接口

    问题描述: 具体问题就是在隐式使用接口变量后,在FreeLibrary执行后,就会出现一个非法访址的错误. 这个错误的原因就是在FreeLibrary后,DLL以的代码均为不可用状态,而在代码执行完整 ...

  5. 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 ...

  6. 【转】Delphi调用webservice总结

    原文:http://www.cnblogs.com/zhangzhifeng/archive/2013/08/15/3259084.html Delphi调用C#写的webservice 用delph ...

  7. Delphi 调用netsh命令修改IP地址

    Delphi 调用netsh命令修改IP地址 先介绍一下Netsh命令的使用方法: 在这里跟大家介绍几个简单的指令 1.Show IP 1.1Cmd Mode 直接在cmd下面输入 netsh int ...

  8. 教程-Delphi调用C# WEBSERVICE(二)

    第二步:将webserivce的WSDL导入到该dll工程中,如何导,方法至少有两种,我说简单的一种:  file->new->other->WebService->WSDL ...

  9. [转]Delphi调用cmd的两种方法

    delphi调用cmd的两种方法vars:string;begins:='cmd.exe /c '+edit1.Text+' >c:\1.txt';winexec(pchar(s),sw_hid ...

随机推荐

  1. 如何让textarea placeholder 文字垂直居中

    <!DOCTYPE html><html lang="en"><head> <meta charset="UTF-8" ...

  2. S3C2440 移植最新5.2linux内核

    基于 移植uboot后. 1. 移植linux内核 1.1 下载源码 打开 https://www.kernel.org/ 直接肝最新的 5.2.8 下载完后,在ubuntu里解压备用. 1.2 搭建 ...

  3. js及jquery常用代码

    1.获取屏幕尺寸 document.documentElement.scrollWidth; document.documentElement.scrollHeight; $(window).widt ...

  4. .net core + mvc 手撸一个代码生成器

    最近闲来无事,总想倒腾点什么,索性弄下代码生成器,这里感谢叶老板FreeSql的强大支持. 以前也用过两款不错的代码生成器,这里说说我的看法 1.动软代码生成器,优点很明显,免费,简单,但是没法高度自 ...

  5. JVM调优实战:G1中的to-space exhausted问题

    最近刚刚将自己的一个应用从CMS升级到G1,在一天早上,刚刚到办公室坐下,就收到手机一阵报警,去查看了监控,发现机器的内存出现了一个90度的涨幅,如下图所示: 在查看GC日志后,发现那个时间点附近出现 ...

  6. 安排:《蚂蚁花呗1234面:Redis+分布式架构+MySQL+linux+红黑树》

    前言: 大厂面试机会难得,为了提高面试通关率,建议朋友们在面试前先复盘自己的知识栈,依据掌握程度划分重要.优先级,系统地去学习!如果不准备充分就去参加面试,既会失去进入大厂的机会,更是对自己的不负责. ...

  7. Codeforces 1009G

    题意略. 思路: 首先是贪心, 我们从前往后依次从小到大考虑放哪个字符, 重点是判断放了这个字符后, 对于剩下的后缀是否存在合法解. 考虑每个位置的允许放的字符集合只有2 ^ 6种, 我们预处理一个后 ...

  8. Leetcode Weekly Contest 152

    退役老人现在连leetcode都不会做了 = = 今天早上做了leetcode第三题题目看错了,加上比赛中间还在调投稿的实验,一心二用直接gg 总结下教训就是 本渣现在做题连题目都看不清就开始做.开始 ...

  9. Mac添加中国法定节假日安排

    最近中秋.国庆临近,当大家开始抢票才反应过来,原来假日已然临近,打开mac日历,发现并没有标注节假日安排,发现了这篇文章,写了这篇读后感. 上面的文章介绍使用了两种在苹果系列设备设置中国节假日的方式: ...

  10. [企业微信通知系列]Jenkins发布后自动通知

    一.前言 最近使用Jenkins进行自动化部署,但是部署后,并没有相应的通知,虽然有邮件发送通知,但是发现邮件会受限于接收方的接收设置,导致不能及时看到相关的发布内容.而由于公司使用的是企业微信,因此 ...