开仓放粮了: delphi在命令行执行命令时的2个问题? Delphi / Windows SDK/API http://www.delphi2007.net/DelphiAPI/html/delphi_20061120203959190.html
1: 怎么等待命令执行完后再执行下面的语句 2: 怎么捕获命令产生的错误,并提示出来?
第2个问题值150分啊
1 用WaitForSingleObject 2 var a:TStringList; begin a:=TStringList.Create; try a.LoadFromFile('123.txt'); //不存在这个文件 except on E: Exception do Showmessage('出错:' + E.message); a.Free end; end;
用WaitForSingleObject可行。。
try except on e: exception do showmessage(e.message) end; 这种方法是可行的 还有一种办法在你程序的界面放一个ApplicationEvents 这个控件 在它的Exception事件里写代码 procedure Tfrmo1.ApplicationEvents1Exception(Sender: TObject; E: Exception); Sender就是你的对象 而Exception就是异常
第一个问题用sleep(1000) 就可以解决了吧~~~
可参考下<delphi源代码分析>
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;
JF。。.
第2个问题用debug 有错的话就debug
抢分!
JF。。。。
路过。
jf
1 用WaitForSingleObject 2 try except on E: Exception
大家怎么不看楼主是几个星星的~~~ try except 他会不知道〉?
如果楼主的命令是指DOS命令行的话, 则必须使用 CreateProcess 建议命令进程 然后使用Wait函数(如: WaitForSingleObject) 等待进程的Handle
接粮
接粮
再接粮
接分
第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个没试过
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;
我来回答第二个问题。 上边回答的都是自己的程序出异常,实际中,你在调用外部程序发生异常后出错时,一般的程序都会将错误输出到标准错误(STDERR),所以,你只要能读到他的STDERR或STDOUT(标准输出)就行了. 读取方法: 1.象楼上那样,用一个命名管道 2.有一个控件的,名字不记得了.... 3.加上命令行参数,将标准输出和错误输出存到文件中....如下: mCommand := "test.exe >a.txt 2>b.txt"; winexec(mCommand); 这样在执行过后,标准输出就写入了 a.txt, 错误输出就写入了b.txt 不一定能帮上你的忙,只是提供一个思路.
|
请发表评论