开仓放粮了: delphi在命令行执行命令时的2个问题?

frogshero 2006-11-20 08:39:59
1: 怎么等待命令执行完后再执行下面的语句
2: 怎么捕获命令产生的错误,并提示出来?
...全文
466 23 打赏 收藏 转发到动态 举报
写回复
用AI写文章
23 条回复
切换为时间正序
请发表友善的回复…
发表回复
hydonlee 2006-12-01
  • 打赏
  • 举报
回复

我来回答第二个问题。 上边回答的都是自己的程序出异常,实际中,你在调用外部程序发生异常后出错时,一般的程序都会将错误输出到标准错误(STDERR),所以,你只要能读到他的STDERR或STDOUT(标准输出)就行了.

读取方法:
1.象楼上那样,用一个命名管道
2.有一个控件的,名字不记得了....
3.加上命令行参数,将标准输出和错误输出存到文件中....如下:

mCommand := "test.exe >a.txt 2>b.txt";
winexec(mCommand);

这样在执行过后,标准输出就写入了 a.txt, 错误输出就写入了b.txt

不一定能帮上你的忙,只是提供一个思路.
keyz 2006-12-01
  • 打赏
  • 举报
回复
procedure CaptureConsoleOutput(DosApp : string;AMemo : TMemo);
const
ReadBuffer = 1048576; // 1 MB Buffer
var
Security : TSecurityAttributes;
ReadPipe,WritePipe : THandle;
start : TStartUpInfo;
ProcessInfo : TProcessInformation;
Buffer : Pchar;
TotalBytesRead,
BytesRead : DWORD;
Apprunning,n,
BytesLeftThisMessage,
TotalBytesAvail : integer;
begin
with Security do
begin
nlength := SizeOf(TSecurityAttributes);
binherithandle := true;
lpsecuritydescriptor := nil;
end;

if CreatePipe (ReadPipe, WritePipe, @Security, 0) then
begin
// Redirect In- and Output through STARTUPINFO structure

Buffer := AllocMem(ReadBuffer + 1);
FillChar(Start,Sizeof(Start),#0);
start.cb := SizeOf(start);
start.hStdOutput := WritePipe;
start.hStdInput := ReadPipe;
start.dwFlags := STARTF_USESTDHANDLES + STARTF_USESHOWWINDOW;
start.wShowWindow := SW_HIDE;

// Create a Console Child Process with redirected input and output

if CreateProcess(nil ,PChar(DosApp),
@Security,@Security,
true ,CREATE_NO_WINDOW or NORMAL_PRIORITY_CLASS,
nil ,nil,
start ,ProcessInfo) then
begin
n:=0;
TotalBytesRead:=0;
repeat
// Increase counter to prevent an endless loop if the process is dead
Inc(n,1);

// wait for end of child process
Apprunning := WaitForSingleObject(ProcessInfo.hProcess,100);
Application.ProcessMessages;

// it is important to read from time to time the output information
// so that the pipe is not blocked by an overflow. New information
// can be written from the console app to the pipe only if there is
// enough buffer space.

if not PeekNamedPipe(ReadPipe ,@Buffer[TotalBytesRead],
ReadBuffer ,@BytesRead,
@TotalBytesAvail,@BytesLeftThisMessage) then break
else if BytesRead > 0 then
ReadFile(ReadPipe,Buffer[TotalBytesRead],BytesRead,BytesRead,nil);
TotalBytesRead:=TotalBytesRead+BytesRead;
until (Apprunning <> WAIT_TIMEOUT) or (n > 150);

Buffer[TotalBytesRead]:= #0;
OemToChar(Buffer,Buffer);
AMemo.Text := AMemo.text + StrPas(Buffer);
end;
FreeMem(Buffer);
CloseHandle(ProcessInfo.hProcess);
CloseHandle(ProcessInfo.hThread);
CloseHandle(ReadPipe);
CloseHandle(WritePipe);
end;
end;
xzhifei 2006-12-01
  • 打赏
  • 举报
回复
第1个问题:
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;
ExitCode: DWORD;
begin
StrPCopy(zAppName, FileName);
GetDir(0, WorkDir);
StrPCopy(zCurDir, WorkDir);
FillChar(StartupInfo, Sizeof(StartupInfo), #0);
StartupInfo.cb := Sizeof(StartupInfo);
StartupInfo.dwFlags := 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);
GetExitCodeProcess(ProcessInfo.hProcess, ExitCode);
Result:=ExitCode;
end;
end;

第2个没试过
tomyan 2006-11-30
  • 打赏
  • 举报
回复
接分
Rex_love_Burger 2006-11-27
  • 打赏
  • 举报
回复
再接粮
Rex_love_Burger 2006-11-27
  • 打赏
  • 举报
回复
接粮
Rex_love_Burger 2006-11-27
  • 打赏
  • 举报
回复
接粮
spirit_sheng 2006-11-27
  • 打赏
  • 举报
回复
如果楼主的命令是指DOS命令行的话, 则必须使用
CreateProcess 建议命令进程
然后使用Wait函数(如: WaitForSingleObject) 等待进程的Handle
hangzhou_hammer 2006-11-27
  • 打赏
  • 举报
回复
大家怎么不看楼主是几个星星的~~~
try

except

他会不知道〉?
real_name 2006-11-22
  • 打赏
  • 举报
回复
1 用WaitForSingleObject

2 try
except
on E: Exception
zczb 2006-11-22
  • 打赏
  • 举报
回复
jf
wudi_1982 2006-11-22
  • 打赏
  • 举报
回复
路过。
StarRains 2006-11-22
  • 打赏
  • 举报
回复
JF。。。。
Rex_love_Burger 2006-11-22
  • 打赏
  • 举报
回复
抢分!
pzl625 2006-11-21
  • 打赏
  • 举报
回复
第2个问题用debug
有错的话就debug
GARNETT2183 2006-11-21
  • 打赏
  • 举报
回复
JF。。.
woshihaoge 2006-11-21
  • 打赏
  • 举报
回复
1.用WaitForSingleObject
procedure TForm1.Button1Click(Sender: TObject);
var
MutexHandle:THandle;
begin
WaitForSingleObject(MutexHandle,INFINITE);
//do your code
CloseHandle(MutexHandle);
end;


2.var
List:TStringList;
begin
List:=TStringList.Create;
try
//do something error
except
on E: Exception do
Showmessage(E.message);
a.Free
end;
end;

daviddelphilee 2006-11-21
  • 打赏
  • 举报
回复
可参考下<delphi源代码分析>
zuoansuifeng 2006-11-21
  • 打赏
  • 举报
回复
第一个问题用sleep(1000) 就可以解决了吧~~~

zuoansuifeng 2006-11-21
  • 打赏
  • 举报
回复
try

except
on e: exception do
showmessage(e.message)
end;

这种方法是可行的

还有一种办法在你程序的界面放一个ApplicationEvents 这个控件

在它的Exception事件里写代码

procedure Tfrmo1.ApplicationEvents1Exception(Sender: TObject;
E: Exception);

Sender就是你的对象 而Exception就是异常
加载更多回复(3)

1,183

社区成员

发帖
与我相关
我的任务
社区描述
Delphi Windows SDK/API
社区管理员
  • Windows SDK/API社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧