可能要通过DOS程序的输入流进行操作:
以下供参考
20. 为DOS程序做WINDOWS外壳程序
有时会在程序中调用DOS程序,并且要求得到程序的返回值,这应该如何实现呢?通常在WINDOWS程序中调用外部程序,可以使用ShellExecute或者WinExecute这些API函数,但这些函数并不能得到程序的返回值,今天我们来介绍CreateProcess这个API函数。
函数介绍如下:
BOOL CreateProcess(
LPCTSTR lpApplicationName, // 可执行文件名
LPTSTR lpCommandLine, // 执行命令
LPSECURITY_ATTRIBUTES lpProcessAttributes,
// 指向SECURITY_ATTRIBUTES结构,通常为NULL(nil)
LPSECURITY_ATTRIBUTES lpThreadAttributes, // 同上
BOOL bInheritHandles, // 是否能继承现在的句柄
DWORD dwCreationFlags, // 新进程的参数设定
LPVOID lpEnvironment, // 新进程的环境参数
LPCTSTR lpCurrentDirectory, // 当前目录名
LPSTARTUPINFO lpStartupInfo, // 指向 STARTUPINFO 结构,用于设定一些参数
LPPROCESS_INFORMATION lpProcessInformation
//指向 PROCESS_INFORMATION 结构,用于返回新进程的信息
);
重要结构介绍
STARTUPINFO
(
DWORD cb; //结构大小
LPTSTR lpReserved; //保留,必须为nil
LPTSTR lpDesktop; //进程所在的桌面名,仅NT有效
LPTSTR lpTitle; //进程标题
DWORD dwX;
DWORD dwY;
DWORD dwXSize;
DWORD dwYSize;
DWORD dwXCountChars;
DWORD dwYCountChars;
DWORD dwFillAttribute;
DWORD dwFlags; //显示那些参数有效
WORD wShowWindow; //是否显示窗口
WORD cbReserved2; //保留,必须为0
LPBYTE lpReserved2; //保留,必须为nil
HANDLE hStdInput; //新进程的标准输入句柄
HANDLE hStdOutput; //新进程的标准输出句柄
HANDLE hStdError; //新进程的标准错误句柄
)
程序分析,程序源码下载(ProcessTest.zip)
procedure TMainForm.Button2Click(Sender: TObject);
var
OutHandle:THandle;
sinfo:_STARTUPINFOA;
processinfo:_PROCESS_INFORMATION;
CurFileName:string;
ExitCode:Cardinal;
nCount:integer;
begin
CurFileName:=CurDir+'/temp.txt';
//临时文件名
//create the output file 's handle
OutHandle:=CreateFile(pchar(CurFileName),GENERIC_WRITE,
FILE_SHARE_WRITE,nil,CREATE_ALWAYS,FILE_ATTRIBUTE_NORMAL,0);
//set the start information property
sinfo.cb:=sizeof(sinfo);
sinfo.lpReserved:=nil; //set all reserved property to the defined property
sinfo.lpDesktop:=nil;
sinfo.lpTitle:=nil;
sinfo.dwFlags:=STARTF_USESHOWWINDOW or STARTF_USESTDHANDLES ;
sinfo.wShowWindow:=SW_HIDE;
sinfo.cbReserved2:=0;
sinfo.lpReserved2:=nil;
sinfo.hStdOutput:=OutHandle;//set the output handle
sinfo.hStdInput:=STD_INPUT_HANDLE ;//set to default
sinfo.hStdError:=STD_ERROR_HANDLE ;
if not(CreateProcess(nil,pchar(Edit1.Text),nil,nil,true,
CREATE_NEW_CONSOLE,nil,nil,sinfo,processinfo))
then
begin
ShowMessage('Process can not be created');
CloseHandle(OutHandle);
end;
nCount:=0;
//set the time out
//wait for process stop
while (GetExitCodeProcess(processinfo.hProcess,ExitCode))and
(ExitCode=STILL_ACTIVE)and(nCount<MaxCount) do
begin
Sleep(500);
inc(nCount);
end;
if not(GetExitCodeProcess(processinfo.hProcess,ExitCode)) or
(ExitCode=STILL_ACTIVE) then //time out , mannualy close process
TerminateProcess(processinfo.hProcess,0);
CloseHandle(OutHandle);
//load the output to the memo
memo1.Lines.LoadFromFile(CurFileName);
end;
123. 获得Dos程序的输出屏幕内容
在Delphi程序中如何获得Dos程序的输出屏幕内容(像Delphi编译器 后台执行Dos编译程序,而在IDE界面下给处系统的编译器输出信息)
利用DOS程序的输出重定向功能 dir >> aa.txt 将DOS程序的输出内容生成临时文件aa.txt,使用DELPHI的FileOpen、FileRead等函数取得aa.txt文件的内容,即可。
Delphi6 Win2k:
procedure TForm1.btnRunClick(Sender: TObject);
var
hReadPipe,hWritePipe:THandle;
si:STARTUPINFO;
lsa:SECURITY_ATTRIBUTES;
pi
ROCESS_INFORMATION;
mDosScreen:String;
cchReadBuffer
WORD;
ph
Char;
fname
Char;
i,j:integer;
begin
fname:=allocmem(255);
ph:=AllocMem(5000);
lsa.nLength :=sizeof(SECURITY_ATTRIBUTES);
lsa.lpSecurityDescriptor :=nil;
lsa.bInheritHandle :=True;
if CreatePipe(hReadPipe,hWritePipe,@lsa,0)=false then
begin
ShowMessage('Can not create pipe!');
exit;
end;
fillchar(si,sizeof(STARTUPINFO),0);
si.cb :=sizeof(STARTUPINFO);
si.dwFlags :=(STARTF_USESTDHANDLES or STARTF_USESHOWWINDOW);
si.wShowWindow :=SW_HIDE;
si.hStdOutput :=hWritePipe;
StrPCopy(fname,'CMD.EXE /c dir/w');
if CreateProcess( nil, fname, nil, nil, true, 0, nil, nil, si, pi) = False then
begin
ShowMessage('can not create process');
FreeMem(ph);
FreeMem(fname);
Exit;
end;
while(true) do
begin
if not PeekNamedPipe(hReadPipe,ph,1,@cchReadBuffer,nil,nil) then break;
if cchReadBuffer<>0 then
begin
if ReadFile(hReadPipe,ph^,4096,cchReadBuffer,nil)=false then break;
ph[cchReadbuffer]:=chr(0);
Memo1.Lines.Add(ph);
end
else if(WaitForSingleObject(pi.hProcess ,0)=WAIT_OBJECT_0) then break;
Sleep(100);
end;
ph[cchReadBuffer]:=chr(0);
Memo1.Lines.Add(ph);
CloseHandle(hReadPipe);
CloseHandle(pi.hThread);
CloseHandle(pi.hProcess);
CloseHandle(hWritePipe);
FreeMem(ph);
FreeMem(fname);
end;