广告位联系
返回顶部
分享到

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

Delphi 来源:互联网 作者:佚名 发布时间:2022-08-20 08:46:26 人浏览
摘要

背景说明: 前段时间开发一个数据转换的系统,业务逻辑中说明数据需要压缩成.tar.gz格式。 我在Windows系统下采用,先生成批处理文件,然后调用WinExec执行批处理文件,休眠等待一段

背景说明:

前段时间开发一个数据转换的系统,业务逻辑中说明数据需要压缩成.tar.gz格式。

我在Windows系统下采用,先生成批处理文件,然后调用WinExec执行批处理文件,休眠等待一段时间,完成数据的自动压缩。

后来发现,待压缩文件的大小不确定,单纯的执行WinExec时Sleep固定时间,可能导致压缩失败、文件不全或损坏。

优化方案:

取代WinExe用CreateProcess用来启动进程, 执行批处理文件, 同时系统会自动填写TProcessInformation这个结构。

此时程序会自动阻塞到该批处理中,等待批处理句柄的进程结束或超时。这样就能解决压缩损坏问题。

给个实例Demo:

D7代码如下:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

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.

运行效果如下:


版权声明 : 本文内容来源于互联网或用户自行发布贡献,该文观点仅代表原作者本人。本站仅提供信息存储空间服务和不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权, 违法违规的内容, 请发送邮件至2530232025#qq.cn(#换@)举报,一经查实,本站将立刻删除。
原文链接 : https://www.cnblogs.com/jeremywucnblog/archive/2019/09/19/11547941.html
相关文章
  • 本站所有内容来源于互联网或用户自行发布,本站仅提供信息存储空间服务,不拥有版权,不承担法律责任。如有侵犯您的权益,请您联系站长处理!
  • Copyright © 2017-2022 F11.CN All Rights Reserved. F11站长开发者网 版权所有 | 苏ICP备2022031554号-1 | 51LA统计