【求助】如何捕获dos窗口中命令行的执行过程?(100分)

  • 主题发起人 主题发起人 han.lab
  • 开始时间 开始时间
H

han.lab

Unregistered / Unconfirmed
GUEST, unregistred user!
我用createprocess运行了一个命令行程序,同时开启了一个dos窗口。现在我想在将该命令行的输出结果显示到我windows窗口中的memo中。请问如何截获dos窗口中的运行过程?(显示一行一行的内容)<br><br>由于我运行的dos窗口执行的是oracle的imp命令,无法重定向,所以好像无法使用pipe的方式。请问用hook是否可以实现?由于我没有编写过类似的程序,哪位高手可以给个详细的过程和程序说明就最好了。<br><br>多谢!<br><br>先奉上100分,不够可以++++++<br>
 
我也想知道<br><br>使用了历史帖子中介绍的方法<br>但是dir的结果无法显示:can not create process.
 
dos窗口中执行的命令结果可以保存成文本文件,比如 ping server &gt;d:/aa.txt<br>那么把执行结果保存在一个文本文件中再导入memo可以吗?
 
谢谢 迷糊:<br>ping确实可以,但是我用的是oracle中的imp命令将文件导入数据库。该命令可以在dos窗口中直接运行,但是却无法用重定向的方法(&gt;)输出到文件。至少我目前不知道可以重定向它的输出结果。我试过重定向,但是结果仍然在屏幕显示,文本中没有内容。:(<br><br>to whbell:<br>如果命令行下可以重定向,应该可以使用以前帖子中的RunDosInMemo过程。<br>==========================<br>procedure RunDosInMemo(DosApp:String;AMemo:TMemo);<br>const<br>&nbsp; &nbsp;ReadBuffer = 2400;<br>var<br>&nbsp;Security &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;: TSecurityAttributes;<br>&nbsp;ReadPipe,WritePipe &nbsp;: THandle;<br>&nbsp;start &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; : TStartUpInfo;<br>&nbsp;ProcessInfo &nbsp; &nbsp; &nbsp; &nbsp; : TProcessInformation;<br>&nbsp;Buffer &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;: Pchar;<br>&nbsp;BytesRead &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; : DWord;<br>&nbsp;Apprunning &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;: DWord;<br>begin<br>&nbsp;With Security do begin<br>&nbsp; nlength &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;:= SizeOf(TSecurityAttributes);<br>&nbsp; binherithandle &nbsp; &nbsp; &nbsp; := true;<br>&nbsp; lpsecuritydescriptor := nil;<br>&nbsp;end;<br>&nbsp;if Createpipe (ReadPipe, WritePipe, @Security, 0) then begin<br>&nbsp; Buffer &nbsp;:= AllocMem(ReadBuffer + 1);<br>&nbsp; FillChar(Start,Sizeof(Start),#0);<br>&nbsp; start.cb &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;:= SizeOf(start);<br>&nbsp; start.hStdOutput &nbsp;:= WritePipe;<br>&nbsp; start.hStdInput &nbsp; := ReadPipe;<br>&nbsp; start.dwFlags &nbsp; &nbsp; := STARTF_USESTDHANDLES + STARTF_USESHOWWINDOW;<br>&nbsp; start.wShowWindow := SW_HIDE;<br>&nbsp; if CreateProcess(nil,PChar(DosApp),@Security,@Security,true,NORMAL_PRIORITY_CLASS,<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;nil,nil,start,ProcessInfo)<br>&nbsp; then<br>&nbsp; begin<br>&nbsp; &nbsp;repeat<br>&nbsp; &nbsp; Apprunning := WaitForSingleObject(ProcessInfo.hProcess,100);<br>&nbsp; &nbsp; Application.ProcessMessages;<br>&nbsp; &nbsp;until (Apprunning &lt;&gt; WAIT_TIMEOUT);<br>&nbsp; &nbsp; Repeat<br>&nbsp; &nbsp; &nbsp; BytesRead := 0;<br>&nbsp; &nbsp; &nbsp; ReadFile(ReadPipe,Buffer[0],ReadBuffer,BytesRead,nil);<br>&nbsp; &nbsp; &nbsp; Buffer[BytesRead]:= #0;<br>&nbsp; &nbsp; &nbsp; OemToAnsi(Buffer,Buffer);<br>&nbsp; &nbsp; &nbsp; AMemo.Text := AMemo.text + String(Buffer);<br>&nbsp; &nbsp; until (BytesRead &lt; ReadBuffer);<br>&nbsp;end;<br>&nbsp;FreeMem(Buffer);<br>&nbsp;CloseHandle(ProcessInfo.hProcess);<br>&nbsp;CloseHandle(ProcessInfo.hThread);<br>&nbsp;CloseHandle(ReadPipe);<br>&nbsp;CloseHandle(WritePipe);<br>&nbsp;end;<br>end;<br>==========================<br>
 
自己顶一下,请问有什么好方法吗?<br>
 
呵呵,给你想一个最简单的方法。<br>你在执行imp的命令时,用<br>imp 参数 &gt; 1.txt<br>也就是把输出重定向到1.txt文件<br>然后,在memo中loadfromfile('1.txt')就可以了
 
to kfzd:<br>正是由于<br>“imp 参数 &gt; 1.txt”<br>这样的方法无法生成1.txt文件(生成的是一个空文件)。<br>所以我想pipe的方法并不适用我的问题。<br>请知道解决方法的帮帮忙了。<br><br>
 
你的问题我有以下几点看法:<br>1、你说的“我运行的dos窗口执行的是oracle的imp命令,无法重定向,所以好像无法使用pipe的方式”纯属谬论,没有不能重定向的DOS命令,除非此命令本来就没有输出结果,如果你在DOS下都能看到输出结果,就不可能不能重定向到文件。<br>2、最好的解决办法已经给出来了,难道你没有看到吗?就在“han.lab”给你的答案中就有了,当然如果你觉得此法有些麻烦的话,就可以使用DOS的重定向语句。<br>3、在重定向中运用DOS命令需要注意长文件名的使用,因为WIN2K下的DOS命令有两种,一种是支持长文件名的命令,另一种是不支持长文件名的命令,对支持长文件名的命令,使用参数就不用那么复杂,直接写就行了,如果是不支持长文件名的命令,就得转换为短文件名或者使用双引号将你的命令行中的每一个参数引起来,以区别岐意,如执行DELPHI的命令行方式时可以使用“"C:/Program Files/Borland/Delphi5/Bin/delphi32.exe"”(中文引号内的部分)的方式,执行“"DIR" "C:/Program Files" "/w" "&gt;C:/111.TXT"”等方式。
 
to redleaf_wgm:<br><br>我是提出问题的人,我就是han.lab。上面那个解决方法是我自己给出的,可惜无法解决我目前的问题。<br><br>关于您说“纯属谬论”我非常希望是事实,然而我在命令行下直接输入“imp [参数] &gt; 1.txt”,结果仍然显示在了屏幕上,1.txt 中并没有我想要的东西。我在delphi下调用我自己上面提到的过程,程序就死掉了。而我用该过程调用其它命令,如ping,netstat等就都没有问题。<br><br>所以我认为imp这类exe程序无法通过管道的方法截获其输入结果。不知道你“没有不能重定向的DOS命令”的结论从何而来,如果可以,还请告知特殊的设置方法或者考虑。在oracle中还存在类似的exe程序,如sqlplus。其它常用的命令好像还没有发现有类似问题。<br><br>关于你提到的长文件名的问题在这里不存在,所有命令包括输出文件都是很简单的文件名称。<br><br>
 
我不懂什么管道的概念,但是我提醒一点,是不是由于产生那个"1.txt"需要一定的时间,而你却太急于取的输出结果,建议在生成'1.txt'文件后能等待一定的时间间隔Sleep(50),然后看看有什么变化没有。
 
to 黑鹰船长<br><br>谢谢提醒。不过我在dos窗口下直接做&gt;1.txt也无法实现我要的效果,所以……:(<br><br>查到一篇老文http://www.delphibbs.com/delphibbs/dispq.asp?lid=122916<br>里面提到“某些dos程序(如edit)运行是需依附在一个控制台上(console),其输入输出都直接通过控制台(CONIN/CONOUT),而不是标准输入/输出(STDIN/STDOUT)”我想可能处理不同吧?<br><br><br><br><br>
 
后退
顶部