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. 在centos6系列vps装Tomcat8.0

    In the following tutorial you will learn how to install and set-up Apache Tomcat 8 on your CentOS 6 ...

  2. Linux 使用命令 1

    fold : Usage: fold [OPTION]... [FILE]...Wrap input lines in each FILE (standard input by default), w ...

  3. DotNetCore 3.0 助力 WPF本地化

    概览 随着我们的应用程序越来越受欢迎,我们的下一步将要开发多语言功能.方便越来越多的国家使用我们中国的应用程序, 基于 WPF 本地化,我们很多时候使用的是系统资源文件,可是动态切换本地化,就比较麻烦 ...

  4. Java网络编程与NIO详解4:浅析NIO包中的Buffer、Channel 和 Selector

    微信公众号[黄小斜]作者是蚂蚁金服 JAVA 工程师,目前在蚂蚁财富负责后端开发工作,专注于 JAVA 后端技术栈,同时也懂点投资理财,坚持学习和写作,用大厂程序员的视角解读技术与互联网,我的世界里不 ...

  5. PrintWriter out = response.getWriter();乱码解决

     resopnse  request的乱码问题 今天在改项目时,发现这个简单又容易忽视在问题.说起这个问题,比较简单,但也比较容易忽视.下面就具体讲讲这个问什么会出现乱码问题. request乱码指的 ...

  6. GIT和SVN教程

    各种版本控制工具的简单比较 特性 CVS SVN GIT 并发修改 支持 支持 支持 并发提交 不支持 支持 支持 历史轨迹 不支持更名 支持更名 支持更名 分布式 不支持 不支持 支持 SVN SV ...

  7. ajax后台处理响应(java)

    public static final void sendAsJson(HttpServletResponse response, String str) { response.setContentT ...

  8. 随笔编号-08 MYSQL 存储过程,5分钟执行调用过程;

    delimiter //DROP PROCEDUREIF EXISTS jdt.day_instan_data_task// CREATE PROCEDURE jdt.day_instan_data_ ...

  9. PicGo+GitHub:你的最佳免费图床选择!

    # PicGo介绍 这是一款图片上传的工具,目前支持SM.MS图床,微博图床,七牛图床,腾讯云COS,阿里云OSS,Imgur,又拍云,GitHub等图床,未来将支持更多图床. 所以解决问题的思路就是 ...

  10. python 18 re模块

    目录 re 模块 1. 正则表达式 2. 匹配模式 3. 常用方法 re 模块 1. 正则表达式 \w 匹配字母(包含中文)或数字或下划线 \W 匹配非字母(包含中文)或数字或下划线 \s 匹配任意的 ...