通过创建管道进行IO重定向,以获得DOS程序执行输出结果。
可是有些程序好像不能被重定向,哪位老兄有这方面的经验给小弟指点一下。
重定向程序部分如下,信信息的读取在另一个线程中。procedure TfrmMain.BuildBtnClick(Sender: TObject);
var
Application: PChar;
CommandLine: PChar;
StartupInfo: TStartupInfo;
SecurityAttributes: TSecurityAttributes;
ProcessInformation: TProcessInformation;
begin
ConsoleEdit.Clear; SecurityAttributes.nlength := SizeOf(TSecurityAttributes);
SecurityAttributes.bInheritHandle := true;
SecurityAttributes.lpSecurityDescriptor := nil; if not CreatePipe(FromReadHandle, FromWriteHandle, @SecurityAttributes, 0) then
begin
ShowMessage('创建管道失败: ' + IntToStr(GetLastError));
gPipeReady := False;
Exit;
end; {Now redirect our standard handles}
SavedStdOut := GetStdHandle(STD_OUTPUT_HANDLE);
if SavedStdOut = INVALID_HANDLE_VALUE then exit;
SetStdHandle(STD_OUTPUT_HANDLE, FromWriteHandle);
gPipeReady := True;
GetStartupInfo(StartupInfo); // 使用当前进程的启动信息
with StartupInfo do
begin
cb := Sizeof(StartupInfo);
dwFlags := STARTF_USESTDHANDLES + STARTF_USESHOWWINDOW;
wShowWindow := SW_HIDE;
// wShowWindow:=SW_MINIMIZE;
// wShowWindow:=SW_MAXIMIZE;
hStdOutput := FromWriteHandle;
end; Application := nil;
CommandLine := PChar(Trim(CommandBox.Text)); if CreateProcess(
Application, // pointer to name of executable module
CommandLine, // pointer to command line string
nil, // pointer to process security attributes
nil, // pointer to thread security attributes
true, // handle inheritance flag
NORMAL_PRIORITY_CLASS, // creation flags
nil, // pointer to new environment block
nil, // pointer to current directory name
StartupInfo, // pointer to STARTUPINFO
ProcessInformation // pointer to PROCESS_INFORMATION
) // succeed return nonzero; fails return zero
then
begin
WaitForSingleObject(ProcessInformation.hProcess, INFINITE); SetStdHandle(STD_OUTPUT_HANDLE, SavedStdOut);
CloseHandle(FromWriteHandle);
end else
begin
gPipeReady := False;
ShowMessage('进程创建失败: ' + IntToStr(GetLastError));
CloseHandle(FromWriteHandle);
CloseHandle(FromReadHandle);
end;
end;
可是有些程序好像不能被重定向,哪位老兄有这方面的经验给小弟指点一下。
重定向程序部分如下,信信息的读取在另一个线程中。procedure TfrmMain.BuildBtnClick(Sender: TObject);
var
Application: PChar;
CommandLine: PChar;
StartupInfo: TStartupInfo;
SecurityAttributes: TSecurityAttributes;
ProcessInformation: TProcessInformation;
begin
ConsoleEdit.Clear; SecurityAttributes.nlength := SizeOf(TSecurityAttributes);
SecurityAttributes.bInheritHandle := true;
SecurityAttributes.lpSecurityDescriptor := nil; if not CreatePipe(FromReadHandle, FromWriteHandle, @SecurityAttributes, 0) then
begin
ShowMessage('创建管道失败: ' + IntToStr(GetLastError));
gPipeReady := False;
Exit;
end; {Now redirect our standard handles}
SavedStdOut := GetStdHandle(STD_OUTPUT_HANDLE);
if SavedStdOut = INVALID_HANDLE_VALUE then exit;
SetStdHandle(STD_OUTPUT_HANDLE, FromWriteHandle);
gPipeReady := True;
GetStartupInfo(StartupInfo); // 使用当前进程的启动信息
with StartupInfo do
begin
cb := Sizeof(StartupInfo);
dwFlags := STARTF_USESTDHANDLES + STARTF_USESHOWWINDOW;
wShowWindow := SW_HIDE;
// wShowWindow:=SW_MINIMIZE;
// wShowWindow:=SW_MAXIMIZE;
hStdOutput := FromWriteHandle;
end; Application := nil;
CommandLine := PChar(Trim(CommandBox.Text)); if CreateProcess(
Application, // pointer to name of executable module
CommandLine, // pointer to command line string
nil, // pointer to process security attributes
nil, // pointer to thread security attributes
true, // handle inheritance flag
NORMAL_PRIORITY_CLASS, // creation flags
nil, // pointer to new environment block
nil, // pointer to current directory name
StartupInfo, // pointer to STARTUPINFO
ProcessInformation // pointer to PROCESS_INFORMATION
) // succeed return nonzero; fails return zero
then
begin
WaitForSingleObject(ProcessInformation.hProcess, INFINITE); SetStdHandle(STD_OUTPUT_HANDLE, SavedStdOut);
CloseHandle(FromWriteHandle);
end else
begin
gPipeReady := False;
ShowMessage('进程创建失败: ' + IntToStr(GetLastError));
CloseHandle(FromWriteHandle);
CloseHandle(FromReadHandle);
end;
end;
还不一样??都是API调用嘛
with StartupInfo do
begin
cb := Sizeof(StartupInfo);
dwFlags := STARTF_USESTDHANDLES + STARTF_USESHOWWINDOW;
wShowWindow := SW_HIDE;
// wShowWindow:=SW_MINIMIZE;
// wShowWindow:=SW_MAXIMIZE;
hStdOutput := FromWriteHandle;
hStdErrput := FromWriteHandle; //有的输出是以错误的输出方式输出的,这样试试
end;