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), #0);
 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.

运行效果如下:

总结

以上所述是小编给大家介绍的Delphi 调用外部程序并阻塞到外部程序中,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对我们网站的支持!
如果你觉得本文对你有帮助,欢迎转载,烦请注明出处,谢谢!

(0)

相关推荐

  • Delphi使用大图标编译程序的方法

    在Windows Vista. Windows7以上Windows系统中可以支持大图标显示了,但是Delphi编译出来的程序却只能显示32x32的图标,这使Delphi编译的程序看起来很不专业.下面就把Delphi编译大图标程序的方法分享一下. 要想使用大图标编译,首先要准备一个256x256的图标图片. 使用图标编辑软件,如IconWorkshop打开你的 ico文件,新建一个256x256的真彩色图标,将你的图片文件导入到该图标中.保存图标后,将图标文件拷贝到你的工程目录下,假设为maini

  • delphi简单判断程序30秒没有键盘和鼠标动作示例

    以下为原代码: (这里给timer设置了1000ms)的参数,表示30秒的间隔!! 复制代码 代码如下: unit Unit1; interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls, ExtCtrls; type TForm1 = class(TForm) Memo1: TMemo; Button1: TButton; Timer1:

  • Delphi2007编译的程序在Win7下图标模糊的解决办法

    使用Delphi2007编译GUI程序的时候会发现在Win7的状态栏中显示的程序图标非常模糊,如果原始的图标清晰度怎么样.造成这样结果的原因是因为Delphi2007生成的icon图标只符合XP等系统的要求,没有对Win7进行优化处理.网上有很多处理的方式,后来找到一个最简单有效的方法,就是只设置项目的图标而不要设置Form窗口的图标. 参考资料: Blurred Delphi Form Icon in Windows 7 Taskbar Delphi form icons are blurry

  • delphi mysql adbquery数据提供程序或其他服务返回 E_FAIL 状态

    delphi mysql adbquery数据提供程序或其他服务返回 E_FAIL 状态.. 出现以上错误,请检查表的时间字段是否可以为NULL,不能为NULL可能出现这个问题,或其他不能为空的字段造成的. Access数据库,文本类型字段,存储字符段超出该字段定义的最大长度报此错误 一般都是数据库字段类型设置不当引起,大家可以检查下.

  • delphi程序全屏显示无标题栏覆盖整个屏幕(适合屏保)

    delphi 程序全屏显示无标题栏,覆盖整个屏幕,这个在做工控机或屏保时有用的,所以记下 复制代码 代码如下: procedure TMainFrm.FormCreate(Sender: TObject); begin with MainFrm do begin { Position form } Top := 0 ; Left := 0 ; { Go full screen} BorderStyle := bsNone ; WindowState := wsmaximized; ClientW

  • Delphi 调用外部程序并阻塞到外部程序中

    背景说明: 前段时间开发一个数据转换的系统,业务逻辑中说明数据需要压缩成.tar.gz格式. 我在Windows系统下采用,先生成批处理文件,然后调用WinExec执行批处理文件,休眠等待一段时间,完成数据的自动压缩. 后来发现,待压缩文件的大小不确定,单纯的执行WinExec时Sleep固定时间,可能导致压缩失败.文件不全或损坏. 优化方案: 取代WinExe用CreateProcess用来启动进程, 执行批处理文件, 同时系统会自动填写TProcessInformation这个结构. 此时程

  • Java基于Runtime调用外部程序出现阻塞的解决方法

    本文实例讲述了Java基于Runtime调用外部程序出现阻塞的解决方法, 是一个很实用的技巧.分享给大家供大家参考.具体分析如下: 有时候在java代码中会调用一些外部程序,比如SwfTools来转换swf.ffmpeg来转换视频等.如果你的代码这样写:Runtime.getRuntime().exec(command),会发现程序一下就执行完毕,而在命令行里要执行一会,是因为java没有等待外部程序的执行完毕,此时就需要使用阻塞,来等待外部程序执行结果: InputStream stderr

  • java调用process线程阻塞问题的解决

    java调用process线程阻塞问题 项目需求中涉及java调用.bat文件进行图像处理,先直接上简略版程序 public void draw(){ //调用bat脚本进行图像处理 Process process = null; InputStream in = null; try { process = Runtime.getRuntime().exec("startup.bat"); //输出测试 // in = process.getInputStream(); // Stri

  • node.js回调函数之阻塞调用与非阻塞调用

    首先,node.js作为javascript运行平台,它采用了事件驱动和异步编程的方式,通过事件注册和异步函数,开发人员可以提高资源利用率,服务器的性能也能得到改善.其次,对于前端人来说,node.js作为js的运行平台,我们可以通过编写系统级或者服务器端的javascript代码交给node.js来执行,让我们前端人也能作用于后台,相比之下,浏览器端的javascript代码在运行时会受到各种安全性的限制,对客户系统的操作有限,而node.js则是一个全面的后台运行时,为javascript提

  • 微服务间调用Retrofit在Spring Cloud Alibaba中的使用

    目录 前置知识 搭建 使用 集成与配置 服务间调用 服务限流 熔断降级 总结 前置知识 在微服务项目中,如果我们想实现服务间调用,一般会选择Feign.之前介绍过一款HTTP客户端工具Retrofit,配合SpringBoot非常好用!其实Retrofit不仅支持普通的HTTP调用,还能支持微服务间的调用,负载均衡和熔断限流都能实现.今天我们来介绍下Retrofit在Spring Cloud Alibaba下的使用,希望对大家有所帮助! SpringBoot实战电商项目mall(50k+star

  • Java 进程执行外部程序造成阻塞的一种原因

    查了好多资料,差点就动手翻Java源码了,最后结合一篇文章(忘记出处了),想到了输出流会阻塞进程执行. Java进程执行有一个输入流,两个输出流(相对于外部程序).当两个输出流有内容输出,而Java执行程序没有及时清空输出流时就会阻塞进程. 现贴出代码,希望能帮助到有需要的同行: 复制代码 代码如下: /**  * pdf转swf函数  * @param path 输入输出文件路径  * @param inputFileName 输入文件名  * @param outputFileName 输出

  • Java Process与Runtime()的使用及调用cmd命令阻塞的解决方案

    Java Process与Runtime()使用 java调用cmd执行bat文件有时会出现卡死的现象,当时感觉很迷惑,后来查资料,本来一般都是这样来调用程序并获取进程的输出流的,但是我在windows上执行这样的调用的时候却总是在while那里被堵塞了,结果造成ffmpeg程序在执行了一会后不再执行,这里从官方的参考文档中我们可以看到这是由于缓冲区的问题,由于java进程没有清空ffmpeg程序写到缓冲区的内容,结果导致ffmpeg程序一直在等待. 在网上也查找了很多这样的问题,不过说的都是使

  • C#使用Process类调用外部程序分解

    在程序开发中,一个程序经常需要去调用其他的程序,C#中Process类正好提供了这样的功能.它提供对本地和远程进程的访问并使您能够启动和停止本地系统进程. 一.启动进程实例 复制代码 代码如下: Process myProcess = new Process();   try  {       myProcess.StartInfo.UseShellExecute = false;       myProcess.StartInfo.FileName = "test.exe";    

  • Java魔法堂之调用外部程序的方法

    前言 Java虽然五脏俱全但总有软肋,譬如获取CPU等硬件信息,当然我们可以通过JNI调用C/C++来获取,但对于对C/C++和Windows API不熟的码农是一系列复杂的学习和踩坑过程.那能不能通过简单一些.学习成本低一些的方式呢?答案是肯定的,在功能实现放在首位的情况下,借他山之石是最简洁有力的做法. 认识java.lang.Runtime#exec方法 作用:用于调用外部程序,并重定向外部程序的标准输入.标准输出和标准错误到缓冲池.功能就是和windows的"运行"一样. 重载

  • PHP调用外部程序的方法解析

    目录 前提:PHP没有运行在安全模式 1. exec 2. system 3. passthru 4. popen 5. proc_open 6. shell_exec 7. 反撇号` 8.cntl_exec 10.  dl() 11.  内核变量 很多情况下需要php调用其他程序如shell命令.shell脚本.可执行程序等等,此时需要使用到诸如exec/system/popen/proc_open等函数,每种函数有各自适合使用的场景以及需要注意的地方. 前提:PHP没有运行在安全模式 如果P

随机推荐