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

开仓放粮了: 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    
   
  不一定能帮上你的忙,只是提供一个思路.

posted on 2008-11-27 21:09  delphi2007  阅读(347)  评论(0编辑  收藏  举报