送分300,高手请进!如何实现调用DOS程序的时候的管道输入重定向!(300分)

  • 主题发起人 主题发起人 战鹰
  • 开始时间 开始时间

战鹰

Unregistered / Unconfirmed
GUEST, unregistred user!
俺需要一个类似下面的方法!
send.exe <pic.BMP >report.txt
不过要求通过程序声称pic.bmp的数据且不通过程序中转直接输出给已经运行的DOS下程序
send.exe并获得其运行结果的字符输出!因为同时可能有多个调用所以不能通过文件中转!
 
我以前好像在一本winapi32 的书看过
 
难道没有人会吗?
 
function GetDosOutput(const CommandLine:string): string;
; var
; ; SA: TSecurityAttributes;
; ; SI: TStartupInfo;
; ; PI: TProcessInformation;
; ; StdOutPipeRead, StdOutPipeWrite: THandle;
; ; WasOK: Boolean;
; ; Buffer: array[0..255] of Char;
; ; BytesRead: Cardinal;
; ; WorkDir, Line: String;
; begin
; ; Application.ProcessMessages;
; ; with SA do
; ; begin
; ; ; nLength := SizeOf(SA);
; ; ; bInheritHandle := True;
; ; ; lpSecurityDescriptor := nil;
; ; end;
; ; // create pipe for standard output redirection
; ; CreatePipe(StdOutPipeRead, ;// read handle
; ; ; ; ; ; ; ;StdOutPipeWrite, // write handle
; ; ; ; ; ; ; ;@SA, ; ; ; ; ; ; // security attributes
; ; ; ; ; ; ; ;0 ; ; ; ; ; ; ; ;// number of bytes reserved for pipe - 0 default
; ; ; ; ; ; ; ;);
; ; try
; ; ; // Make child process use StdOutPipeWrite as standard out,
; ; ; // and make sure it does not show on screen.
; ; ; with SI do
; ; ; begin
; ; ; ; FillChar(SI, SizeOf(SI), 0);
; ; ; ; cb := SizeOf(SI);
; ; ; ; dwFlags := STARTF_USESHOWWINDOW or STARTF_USESTDHANDLES;
; ; ; ; wShowWindow := SW_HIDE;
; ; ; ; hStdInput := GetStdHandle(STD_INPUT_HANDLE); // don't redirect stdinput
; ; ; ; hStdOutput := StdOutPipeWrite;
; ; ; ; hStdError := StdOutPipeWrite;
; ; ; end;

; ; ; // launch the command line compiler
; ; ; WorkDir := ExtractFilePath(CommandLine);
; ; ; WasOK := CreateProcess(nil, PChar(CommandLine), nil, nil, True, 0, nil,
; ; ; ; ; ; ; ; ; ; ; ; ; ; ;PChar(WorkDir), SI, PI);
;
; ; ; // Now that the handle has been inherited, close write to be safe.
; ; ; // We don't want to read or write to it accidentally.
; ; ; CloseHandle(StdOutPipeWrite);
; ; ; // if process could be created then handle its output
; ; ; if not WasOK then
; ; ; ; raise Exception.Create('Could not execute command line!')
; ; ; else
; ; ; ; try
; ; ; ; ; // get all output until dos app finishes
; ; ; ; ; Line := '';
; ; ; ; ; repeat
; ; ; ; ; ; // read block of characters (might contain carriage returns and line feeds)
; ; ; ; ; ; WasOK := ReadFile(StdOutPipeRead, Buffer, 255, BytesRead, nil);

; ; ; ; ; ; // has anything been read?
; ; ; ; ; ; if BytesRead > 0 then
; ; ; ; ; ; begin
; ; ; ; ; ; ; // finish buffer to PChar
; ; ; ; ; ; ; Buffer[BytesRead] := #0;
; ; ; ; ; ; ; // combine the buffer with the rest of the last run
; ; ; ; ; ; ; Line := Line + Buffer;
; ; ; ; ; ; end;
; ; ; ; ; until not WasOK or (BytesRead = 0);
; ; ; ; ; // wait for console app to finish (should be already at this point)
; ; ; ; ; WaitForSingleObject(PI.hProcess, INFINITE);
; ; ; ; finally
; ; ; ; ; // Close all remaining handles
; ; ; ; ; CloseHandle(PI.hThread);
; ; ; ; ; CloseHandle(PI.hProcess);
; ; ; ; end;
; ; finally
; ; ; ; result:=Line;
; ; ; ; CloseHandle(StdOutPipeRead);
; ; end;
; end;
 
to tseug,
我现在用的代码和你类似,但是我需要能够在
CreateProcess和ReadFile
之间向DOS程序发送一些数据,比如用WriteFile
但不知道文件句柄用什么!你能高速我吗?
 
那你还要建立一个管道, 重定向 STD_INPUT_HANDLE, CreateProcess之后, 写这个管道就
可以了.
 
to tseug,
拜托可以说得详细点吗?以前没有接触过这方面的知识!
另外你的例子里
;hStdInput := GetStdHandle(STD_INPUT_HANDLE); // don't redirect stdinput
是什么用途?
 
tseug
在吗?
 
作个批处理加个参数,
再调用批处理。
 
to wk_knife
恐怕不行,因为要动态调用多个进程,如果要动态生成批处理文件的话,
要么可能产生垃圾文件,要么可能出现重复调用的问题,少量的调用可行
但是如果多了就不行了!
 
procedure Redirect(const aExecuteFile:string;
; ; ; ; ; ; ; ; ; ;const aInputFile ;:string;
; ; ; ; ; ; ; ; ; ;const aOutputFile :string);

var
; SI: TStartupInfo;
; PI: TProcessInformation;
; hInput, hOutput : THandle;
; WorkDir: string;
; bOk: Boolean;
begin

; hInput := FileOpen(aInputFile, fmOpenRead);
; hOutput:= FileCreate(aOutputFile);

; try
; ; // Make child process use StdOutPipeWrite as standard out,
; ; // and make sure it does not show on screen.
; ; with SI do
; ; ; begin
; ; ; FillChar(SI, SizeOf(SI), 0);
; ; ; cb := SizeOf(SI);
; ; ; dwFlags := STARTF_USESHOWWINDOW or STARTF_USESTDHANDLES;
; ; ; wShowWindow := SW_HIDE;
; ; ; hStdInput := hInput;
; ; ; hStdOutput:= hOutput;
; ; ; hStdError := hOutput;
; ; ; end;

; ; // launch the command line compiler
; ; WorkDir := ExtractFilePath(aExecuteFile);
; ; bOK := CreateProcess(nil, PChar(aExecuteFile), nil, nil, True, 0, nil,
; ; ; ; ; ; ; ; ; ; ; ; ; ; ;PChar(WorkDir), SI, PI);

; ; try
; ; ; // if process could be created then handle its output
; ; ; if not bOK then raise Exception.Create('Could not run ' + aExecuteFile);
; ; ; WaitForSingleObject(PI.hProcess, INFINITE);

; ; finally
; ; ; // Close all remaining handles
; ; ; CloseHandle(PI.hThread);
; ; ; CloseHandle(PI.hProcess);
; ; end;

; finally
; ; FileClose(hInput);
; ; FileClose(hOutput);
; end;
end;
 
看看上面的代码, 你应该明白重定向的含义了. 你只要得到合适的句柄, 可以把输入输
出重定向到你想要的地方. 句柄可以是文件, 也可以是管道, 你只要指定好
hStdInput(标准输入),hStdOutput(标准输出),hStdError(标准错误) 就可以了.
 
终于弄明白了!
果然是高人!
 
该贴子里的内容解决了隐式调用Dos或Win32程序的问题并可以向被调用的程序输出数据并
可以接收被调用程序的输出!

建议斑竹将其加入精华区!
 
看得出来,tseug是一个高手。
不过,我对您给出的程序源代码还有一点小小的要求,不知tseug能不能满足我们这些
Delphi的初学者。那就是对给出的程序多加一点儿注释。不仅仅是在程序当中加入,
在函数头也请加上一些。比如程序所运行的操作系统平台、在Delphi的什么版本调试
通过、函数调用样例等等。
这些细节虽然不太重要,可是要弄清楚却很烦人。
一点浅识薄见,让高手见笑了。
 
后退
顶部