关于截获一个由perl编写的dos控制台程序的输出信息的问题。(200分)

  • 主题发起人 主题发起人 slugger
  • 开始时间 开始时间
S

slugger

Unregistered / Unconfirmed
GUEST, unregistred user!
我想截获一个由perl编写的dos控制台程序的输出信息并实时显示在我自己的程序上,在论坛上查找了几天,基本上都是使用管道重定向的方法来实现,于是我就参考前辈们的代码自己编了小程序,可是这个小程序对于dos的命令(如cdm、help、ping等)都能截获并正常显示,就是对我想要截获的那个由perl编写的dos控制台程序不奏效。我说明一下,我的小程序只能截获到一小部分信息,而这小部分的信息是被截获程序调用一个C语言模块的信息,而且这仅有的信息必须要等被截获程序关闭后才能显示(被截获程序,是一个循环程序,一旦运行就不会结束的,必须手动强制结束)。我又试过重定向到文件,结果和用管道一样,现在正是束手无策,只可到这里来求助,各位高手看看有什么好建议就尽量提出。<br><br>附上我的管道重定向代码:<br>procedure ThreadProcess.Execute;<br>var<br> hReadPipe,hWritePipe:THandle;<br> si:STARTUPINFO;<br> lsa:SECURITY_ATTRIBUTES;<br> pi:PROCESS_INFORMATION;<br> mDosScreen:String;<br> cchReadBuffer:DWORD;<br> ph:PChar;<br> fname:PChar;<br> i,j:integer;<br>begin<br> fname:=allocmem(255);<br> ph:=AllocMem(5000);<br> lsa.nLength :=sizeof(SECURITY_ATTRIBUTES);<br> lsa.lpSecurityDescriptor :=nil;<br> lsa.bInheritHandle :=True;<br><br> if CreatePipe(hReadPipe,hWritePipe,@lsa,0)=false then<br> begin<br> &nbsp; ShowMessage('Can not create pipe!');<br> &nbsp; exit;<br> end;<br> fillchar(si,sizeof(STARTUPINFO),0);<br> si.cb :=sizeof(STARTUPINFO);<br> si.dwFlags :=(STARTF_USESTDHANDLES or STARTF_USESHOWWINDOW);<br> si.wShowWindow :=SW_SHOW;<br> si.hStdOutput :=hWritePipe;<br> StrPCopy(fname,'d:/slu/slu.exe');<br> if CreateProcess( nil, fname, nil, nil, true, 0, nil, 'd:/slu/', si, pi) = False &nbsp;then<br> &nbsp;begin<br> &nbsp; ShowMessage('can not create process');<br> &nbsp; FreeMem(ph);<br> &nbsp; FreeMem(fname);<br> &nbsp; Exit;<br> &nbsp;end;<br> while(true) do<br> begin<br> &nbsp;if not PeekNamedPipe(hReadPipe,ph,1,@cchReadBuffer,nil,nil) then break;<br> &nbsp;if cchReadBuffer&lt;&gt;0 then<br> &nbsp; begin<br> &nbsp; &nbsp; if ReadFile(hReadPipe,ph^,4096,cchReadBuffer,nil)=false then break;<br> &nbsp; &nbsp; ph[cchReadbuffer]:=chr(0);<br> &nbsp; &nbsp; form1.Memo1.Lines.Add(ph);<br> &nbsp; end<br> &nbsp; else if(WaitForSingleObject(pi.hProcess ,0)=WAIT_OBJECT_0) then break;<br> &nbsp; Sleep(100);<br> end;<br> ph[cchReadBuffer]:=chr(0);<br> form1.Memo1.Lines.Add(ph);<br> CloseHandle(hReadPipe);<br> CloseHandle(pi.hThread);<br> CloseHandle(pi.hProcess);<br> CloseHandle(hWritePipe);<br> FreeMem(ph);<br> FreeMem(fname);<br>end;
 
这问题太难吗?高手们来帮帮忙吧!
 
给你一个控件,应该可以用的,我用过不错。<br>http://maxxdelphisite.free.fr/doscmd.htm
 
安装方法如下:<br><br>下载doscommand_tk.zip <br>把DosCommand.pas和DosCommand.dcr复制到Delphi安装目录的Lib文件夹下,运行DELPHI<br>→选择Component → Install Component 弹出安装控件(PAS单元)对话框,选择Browse..<br>按钮,在弹出的打开对话框中选择DosCommand.pas单元,然后按 OK 就可以了
 
To:weiliu<br>控件已经安装,请问如何在delphi中使用?我得要求是把dos控制台(如ping 127.0.0.1 /t)的信息实时输出到我的Memo中。
 
程序如下,够简单吧:<br><br>unit Unit1;<br><br>interface<br><br>uses<br> &nbsp;Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,<br> &nbsp;Dialogs, StdCtrls, DosCommand;<br><br>type<br> &nbsp;TForm1 = class(TForm)<br> &nbsp; &nbsp;Memo1: TMemo;<br> &nbsp; &nbsp;DosCommand1: TDosCommand;<br> &nbsp; &nbsp;Button1: TButton;<br> &nbsp; &nbsp;procedure Button1Click(Sender: TObject);<br> &nbsp;private<br> &nbsp; &nbsp;{ Private declarations }<br> &nbsp;public<br> &nbsp; &nbsp;{ Public declarations }<br> &nbsp;end;<br><br>var<br> &nbsp;Form1: TForm1;<br><br>implementation<br><br>{$R *.dfm}<br><br>procedure TForm1.Button1Click(Sender: TObject);<br>const<br> &nbsp;cmd_line='ping 127.0.0.1 /t';<br>var<br> &nbsp;cmd:TDoscommand;<br>begin<br> &nbsp;cmd:=TDoscommand.Create(nil);<br> &nbsp;cmd.CommandLine:=cmd_line;<br> &nbsp;cmd.OutputLines:=memo1.Lines;<br> &nbsp;cmd.Execute;<br>end;<br><br>end.
 
To:weiliu<br> &nbsp; &nbsp;很感谢你的帮忙,可是你提供的控件效果和我自己写的代码一样,对一般的dos都没问题,对我要截获的程序就没有效果。我也大概看了一下控件的源码,感觉它的实现方式跟我的差不多,都是用CreateProcess创建程序并重定向管道。<br> &nbsp; &nbsp;我要截获的程序是一个游戏外挂程序,因为使用perl编写,所以只能做到dos控制台的形式,因此所有信息都是通过文字方式显示的,所以就有需要通过读取它的文字信息来制作一个GUI界面。<br> &nbsp; &nbsp;其实早已有人写出了这样一个GUI界面程序,只不过是商业软件,加上我对编程的热爱,所以就想自己动手。外挂程序的作者曾经说过这个GUI界面程序是使用管道操作来读取外挂的输出信息的,可是经过一番研究后,管道重定向对外挂不起作用(也很有可能是我的方法不正确)。最后我又发现了那个GUI界面程序中有一个ApiHooks的dll文件,这会不会说明它使用了hook函数呢?又会是对哪个消息进行hook呢?
 
它那个控制台程序的运行结果不能用&gt;定向输出到一个文本文件的吗?<br>如果能,你只需要准备一个程序读这个文本文件好了。
 
后退
顶部