如何判断外部程序是否执行完毕?(100分)

  • 主题发起人 主题发起人 xmhch
  • 开始时间 开始时间
X

xmhch

Unregistered / Unconfirmed
GUEST, unregistred user!
我在程序中使用WinExec调用WINRAR命令行的方式对压缩文件进行解压,然后对解压后的
文件进行处理。但我如何判断文件已经解压完成,也就是说,我如何才能保证程序在解
压完毕后才进行下一步的工作?
 
function WinExecAndWait32(FileName:String; Visibility : integer):integer;
var
zAppName:array[0..512] of char;
zCurDir:array[0..255] of char;
WorkDir:String;
StartupInfo:TStartupInfo;
ProcessInfo:TProcessInformation;
//MyResult:DWORD;

hStdIn:THandle; // standard input handle
//inputBuffer:INPUT_RECORD; //buffer to hold a single console input record
irMacroBuf:INPUT_RECORD; // array of input events
dwBytesWritten : DWORD;

begin
SetConsoleTitle('s');
StrPCopy(zAppName,FileName);
//MainForm.Caption := zappname;
GetDir(0,WorkDir);
StrPCopy(zCurDir,WorkDir);
FillChar(StartupInfo,Sizeof(StartupInfo),#0);
StartupInfo.cb := Sizeof(StartupInfo);
hStdIn:= StartupInfo.hStdInput;
StartupInfo.hStdInput:= hStdIn;
StartupInfo.lpTitle:=@zAppName;
StartupInfo.dwFlags := StartupInfo.dwFlags or STARTF_USESTDHANDLES;

WriteConsoleInput(hStdIn,irMacroBuf,1,dwBytesWritten);

StartupInfo.dwFlags := StartupInfo.dwFlags or STARTF_USESHOWWINDOW;
StartupInfo.wShowWindow := Visibility;
if not CreateProcess(nil,
zAppName, { pointer to command line string }
nil, { pointer to process security attributes }
nil, { pointer to thread security attributes }
false, { handle inheritance flag }
CREATE_NEW_CONSOLE or { creation flags }
NORMAL_PRIORITY_CLASS,
nil, { pointer to new environment block }
nil, { pointer to current directory name }
StartupInfo, { pointer to STARTUPINFO }
ProcessInfo) then Result := -1 { pointer to PROCESS_INF }

else begin
WaitforSingleObject(ProcessInfo.hProcess,INFINITE);
Result:=1;
end;
end;
 
楼上的要等程序执行完才有消息,而且中途没有任何反映。

procedure TFrmHTM.Timer1Timer(Sender: TObject);
//检测程序是否在运行
var
ExeHandle:Thandle;
begin
//获得句柄-->标题确定
ExeHandle:=findWindow(nil,'winrar');//返回句柄
if ExeHandle<>0 then begin
STB.Panels[0].Text := 'Please waiting...';
STB.Panels[1].Text := 'Time: ' + IntToStr(i) + 's';
end
else
begin
STB.Panels[0].Text := 'Successful!';
end;
i := i + 1;
end;
 
to commandor:
你的方法我也考虑过,通过查找WINRAR的句柄,但如果这个WinRar不是由程序调用的,
而是由其他程序调用或单独运行的,哪又该如何区分?
 
生成一个bat文件,在bat中调用rar来压缩,找bat的句并就可以了。
 
zw84611的方法是可行的,如果你非要等待
其他程序打开的,那就先用
findWindow()发现那个程序的ID
例如hProcess:=findWindow(nil,'notepad');
然后用 WaitforSingleObject(hProcess,INFINITE);
就可以了!
 
Function {TCustomExecExtApp.}Execute(ComLine : String):boolean;
var
FAppHandle : THandle;
lpAppName : pchar;
lpTitle : Pchar;
StartInfo : TStartupInfo;
FProcessInfo : TProcessInformation;
begin
if (Length(ComLine)+2)>255 then
begin
SetError(-1,'Command Line Too Long!');
Result := false;
exit;
end;

GetMem(lpAppName,MaxPath);
GetMem(lpTitle,MaxPath);

StrPCopy(lpAppName,ComLine);
StrPCopy(lpTitle,ComLine);
//init StartInformation
StartInfo.cb:=sizeof(TStartupInfo);
StartInfo.lpReserved := NIL;
StartInfo.lpDesktop:=NIL;
StartInfo.lpTitle := lpTitle;
StartInfo.dwFillAttribute := 0;
StartInfo.cbReserved2 :=0;
StartInfo.lpReserved2 := NIL;
//这个参数控制Create Window形态
//STARTF_USESHOWWINDOW 指定这个标志位,指示用ShowWindow的参数建立窗口
StartInfo.dwFlags := STARTF_USESHOWWINDOW;
StartInfo.wShowWindow := FWinStyle;

//CreateProcess 在Windows.pas中的一个原形
//function CreateProcessA(lpApplicationName: PAnsiChar; lpCommandLine: PAnsiChar;
//lpProcessAttributes, lpThreadAttributes: PSecurityAttributes;
//bInheritHandles: BOOL; dwCreationFlags: DWORD; lpEnvironment: Pointer;
//lpCurrentDirectory: PAnsiChar; const lpStartupInfo: TStartupInfo;
//var lpProcessInformation: TProcessInformation): BOOL; stdcall;

//Clear ProcessInfo Structure
FProcessInfo.hProcess := 0;
FProcessInfo.hThread := 0;
FProcessInfo.dwProcessId := 0;
FProcessInfo.dwThreadId := 0;

//Create process
if CreateProcess(NIL,
lpAppName,
nil,
nil,
False,
0,
nil,
nil,
StartInfo,
FProcessInfo) then
begin //Command Executed
//为进程建立可查询的属性。
FAppHandle := OpenProcess(PROCESS_QUERY_INFORMATION,False,FProcessInfo.dwProcessId);
//建立可查询的属性后可用于GetExitCodeProcess,在Delphi中查询外部程序是
//否还在运行,这个函数在W95,W98,NT40下均可用.
//注意:FAppHandle要改成Form的变量,以便其它函数可以使用.
// GetExitCodeProcess(FAppHandle,FAppState);
// if FAppState<>STILL_ACTIVE then
// 外部程序已结束
// else
// 外部程序还在运行
end
else //false Create Process;
begin
SetError(-2,'Can not create process!');
Result := false;
end;

FreeMem(lpAppName);
FreeMem(lpTitle);
end;

 
TO zxbyh:
请问:SetError是什么函数?FAppState是如何定义的?
    StartInfo.wShowWindow := FWinStyle; 编译出错,FWinStyle未定义。
 
多人接受答案了。
 
后退
顶部