实在没办法了,求救来了!(100分)

  • 主题发起人 主题发起人 zanpen2001
  • 开始时间 开始时间
Z

zanpen2001

Unregistered / Unconfirmed
GUEST, unregistred user!
各位:

; ; 我要把Dos的批处理文件的输出弄到我的Windows程序中来,怎么做?
下面的批处理文件名为:test.bat
; ; @echo on
; ; REM 这是一个测试文件。
; ; copy d:/downloads/*.Exe d:/temp/*.exe

在我的程序中调用此程序,然后把它的输出:

D:/REM 这是一个测试文件。

copy d:/downloads/*.Exe d:/temp/*.exe
d:/downloads/1129i32.exe
d:/downloads/1229i32.exe
d:/downloads/QQ2000B.exe
已复制 ; ; ; ; 3 个文件。

实时地弄到我的Memo中来。

请各位高手吝教!
 
Function CopyFile(FromFile,ToFile:String): Boolean;
Var ;
FromF, ToF: file;{$IFDEF WIN32} ;NumRead, NumWritten: Integer;{$ELSE} ;NumRead, NumWritten: Word;{$ENDIF} ;
Buf: array[1..2048] of Char;
Begin
; If IsDir(FromFile) Then ;Begin ; ;
{MessageDlg('在拷贝文件时出现错误。文件名: '+FromFile, ; ; ; ;mtWarning, [mbOk], 0);} ;
;Result := False;
;End ;Else
;Begin ;
; AssignFile(FromF, FromFile); ;
;AssignFile(ToF, ToFile); ; ;
Try
; ; ;FileMode := 0; ;{Sets Reset To ReadOnly} ; ;
; ; ;Reset(FromF, 1);{ Record size = 1 } ; ; ;
; ; ;FileMode := 2; ;{Sets Reset To ReadWrite}
; ; ; Rewrite(ToF, 1);{ Record size = 1 } ; ;
; repeat ; ; ; ;BlockRead(FromF, Buf, SizeOf(Buf), NumRead); ; ; ;
; ; ; ; ; ; ; ; BlockWrite(ToF, Buf, NumRead, NumWritten); ; ;
; ; ; ; ; ; ; ; ; until (NumRead = 0) or (NumWritten <> NumRead); ; ;
; ; ; ; ; ; ; ; ; System.CloseFile(FromF); ; ;
; ; ; ; ; ; ; ; ; ;System.CloseFile(ToF); ;
; ; ; ; ; ; ; ; ; ; ; Result := True; ;
; Except ; ; ;On EInOutError Do ; ; ;
Begin ; ; ;
;Result := False; ; ; ;
End; ; ;
;Else Result := False; ;
;End; ; ;
If Result = False Then ; ;
;MessageDlg('在拷贝文件时出现错误。文件名: '+FromFile, ; ; ; ;mtWarning, [mbOk], 0); ;
End;
End;
 
他是想在执行系统提供的copy命令的情况吧。
 
这样子行不?把copy信息放到一个文档中,再从些文档中读取.
copy tt1.txt d:/tt1.txt >test.txt
 
; ;这些东西都是些华而不实的,没有必要去研究它,多想想方法,用别的方法可能会更好!
 
各位:因为公司的数据库用的是Sybase,在整个数据库安装过程中要建设备,建库,倒库,
都要用到isql命令及Sql语句,现在把它们做成了批处理,而我要在程序中调用这些批处理,
又想要它的实时的结果,用程序中的VCL控件接收,我昨晚查了这里好多次,发现以前有人
做过,是用pipe做的,但说得不够详细,看不明白,所以才再上来问一下。请高手留步,
详加指点。
to zhangkan:你的做法我现在正在用。不过那样的话就不能实时的看到批处理文件的运行
情况了,更不能随时中止它。
比如:下面的SQL语句在一个批处理test.bat中
isql -Usa -P -Shp -imysql.sql
mysql.sql中为:bcp csbt..sys_staff out bcp_txt/sys_staff.txt -Usa -P -Shp -c
; ; ; ; ; ; ; ;bcp ........................
; ; ; ; ; ; ; ;bcp.........................
; ; ; ; ; ; ; ;...
; ; ; ; ; ; ; ;...
我想看到这些bcp的实时执行结果,怎么办?
; ; ;
 
不会帮你up
 
使用InterprocessCommunication (IPC)技术
一个进程得输出可以通过Pipe成为另一个进程得输入(也可以是内存影射)
你可以看一些Msdn有关IPC得说明

或者让高手来继续回答,真是打击自信心啊~
 
利用Win32API的CreateProcess函数可以重定向一个控制台程序的输出,
所以我们可以用一个PIPE管道来读取控制台输出,显示在Windows程序中。

一个不很完美的例子:
...
TForm1 = class(TForm)
...
Memo1 : TMemo; ;// 用来显示命令行结果
Button1: TButton; // 按下后执行命令
Edit1: TEdit; // 输入想要执行的命令
...

procedure TForm1.Button1Click(Sender: TObject);
var
; si: TStartupInfo;
; pi: TProcessInformation;
; rh,wh: THandle;
; Stream: TStream;
; Buffer: array[0..8192] of char;
; rc: DWord;
begin
; // 创建管道
; if CreatePipe(rh,wh,nil,8192) then
; begin
; ; FillChar(si,SizeOf(si),0);
; ; si.dwFlags:=STARTF_USESTDHANDLES; // 指定进程使用StdOupt重定位功能
; ; si.hStdOutput:=wh; // 指定进程的标准输出到管道的写端口
; ; // 创建进程
; ; if CreateProcess(nil,PChar(Edit1.Text),nil,nil,false,
; ; ; DETACHED_PROCESS,nil,nil,si,pi) then
; ; begin
; ; ; // 创建内存流
; ; ; Stream:=TMemoryStream.Create;
; ; ; repeat
; ; ; ; // 查询管道缓冲区内可读的字节数到rc
; ; ; ; if PeekNamedPipe(rh,nil,0,nil,@rc,nil) and (rc>0) then
; ; ; ; begin
; ; ; ; ; // 读管道缓冲区
; ; ; ; ; ReadFile(rh,Buffer,rc,rc,nil);
; ; ; ; ; // 写入内存流
; ; ; ; ; Stream.Write(Buffer,rc);
; ; ; ; end;
; ; ; // 当被调用进程结束且管道中无剩余数据时结束循环
; ; ; until (WaitForSingleObject(pi.hProcess,0)=WAIT_OBJECT_0) and (bs=0);
; ; ; // 读内存流到指定的显示Memo控件中
; ; ; Stream.Position:=0;
; ; ; Memo1.Lines.LoadFromStream(Stream);
; ; ; Stream.Free;
; ; end;
; ; // 关闭管道端口
; ; CloseHandle(rh);
; ; CloseHandle(wh);
; end;
end;

已调试通过,可以运行。

另外用PIPE的好处在于,子进程一边执行中,主进程可以同时获得子进程的输出而
不必等到子进程结束。当然本例中的情况并非如此。但是你只要改一改在ReadFile
后直接将Buffer里的内容加到Memo1的内容后面即可实现。
 
skyweb,谢谢你费心帮我解决问题了!有事儿呼我:*****-********
问题还有:变量bs是什么?为什么没声明?这样的话也不可能调试通过啊?我试了一天,通
不过。如果你有时间,再帮我看看源码好不好?求你了。
 
不好意思,一时疏乎,手误:)
bs(BufferSize)实际应为rc(ReadedChars)。
 
后退
顶部