Текущий архив: 2005.02.20;
Скачать: CL | DM;
ВнизСвой файл вместо STDOUT? Найти похожие ветки
← →
ancara © (2004-12-29 20:58) [0]Доброго времени суток, господа!
Опишу ситуацию: вот есть консольное приложение (не мое), скажем, ping.exe. Если я в командной строке напишу ping.exe, то оно направит на стандартный вывод (STDOUT) некий текст, в частности, как использовать эту программу. (Простите, если коряво называю вещи, хочу просто донести суть...). Задача передо мной такая, надо запустить это приложение при помощи CreateProcess и "сказать", чтобы она писала не на STDOUT а в мой файл. Или поток. Прочитав хэлп про CreateProcess и в частности про структуру _STARTUPINFO я понял что ее поля hStdInput и hStdOutput имеют к этому некое отношение. Я указал в качестве hStdOutput хэндл некоего файла, кот. открыл при помощи OpenFile. Нифига не пашет, в смысле не пишет туда. Флаг STARTF_USESTDHANDLES поставил, bInheritHandle в SECURITY_ATTRIBUTES поставил в true, в CreateProcess передал bInheritHandles как true, вообщем все что в МСДН написано по этому поводу сделал и... никакого эффекта. Подскажите пожалуйста, что я делаю не так и что надо сделать. Заранее очень благодарен.
← →
dimaxx © (2004-12-29 23:37) [1]Копать надоть в сторону CreatePipe - с ее помощью можно перенаправлять выводимую инфу куда угодно.
← →
Дмитрий В. Белькевич (2004-12-30 02:43) [2]FAQ?
← →
ancara © (2004-12-30 09:31) [3]2 dimaxx: спасибо, буду копать.
2 Дмитрий В. Белькевич: и где там? я, честно говоря, туда заглянул, пере тем как спрашивать, но про перенаправление не нашел, не подскажете ссылочку на тему в FAQ"е?
← →
Style © (2004-12-30 10:04) [4]Вот пример по получению STDIN STDOUT консоли. Я думаю сделать запись в файл будет сделать не сложно..
TReadThread = class(TThread)
private
{ Private declarations }
protected
procedure Execute; override;
end;
TConsolePipes = record
hIn_Read, hIn_Write: THandle;
hOut_Read, hOut_Write: THandle;
hEr_Read, hEr_Write: THandle;
end;
Tfrm_Console = class(TForm)
btn_send: TButton;
ed_send: TEdit;
Panel: TPanel;
Memo: TMemo;
procedure FormDestroy(Sender: TObject);
procedure FormCreate(Sender: TObject);
procedure btn_sendClick(Sender: TObject);
procedure ed_sendKeyPress(Sender: TObject; var Key: Char);
private
{ Private declarations }
public
pi: Process_Information;
Pipes: TConsolePipes;
ReadThread: TReadThread;
pExitCode: dword;
procedure ExecConsole(lpCommandLine: string; var lpProcessInformation: PROCESS_INFORMATION);
procedure Send(Handle: THandle; Text: string);
{ Public declarations }
end;
var
frm_Console: Tfrm_Console;
implementation
{$R *.DFM}
function WinToDos(Str: String): String;
var
Mem: pchar;
Size: integer;
begin
Size := Length(Str);
mem := pchar(AllocMem(Size+1));
try
StrPCopy(Mem, Str);
ANSIToOEM(Mem, Mem);
finally
Result := StrPas(Mem);
FreeMem(Mem);
end;
end;
function DosToWin(Str: String): String;
var
Mem: pchar;
Size: integer;
begin
Size := Length(Str);
mem := pchar(AllocMem(Size+1));
try
StrPCopy(Mem, Str);
OEMToAnsi(Mem, Mem);
finally
Result := StrPas(Mem);
FreeMem(Mem);
end;
end;
procedure TReadThread.Execute;
const
Size = 1024;
var
chBuffer: pchar;
cRead: cardinal;
begin
while not Terminated do
begin
chBuffer := pchar(AllocMem(Size+1));
try
if (Windows.ReadFile(Frm_Console.Pipes.hOut_Read, chBuffer^, Size, cRead, nil) ) then
begin
Frm_Console.Memo.Lines.Add(DosToWin(chBuffer));
end;
finally
Freemem(chBuffer);
end;
end;
{ Place thread code here }
end;
procedure Tfrm_Console.ExecConsole(lpCommandLine: string; var lpProcessInformation: PROCESS_INFORMATION);
const
ErPipe = "Can`t Create Pipe!";
ErProcess = "Can`t create process!";
var
bInheritHandles: boolean; // handle inheritance flag
dwCreationFlags: DWORD; // creation flags
lpCurrentDirectory: string;// pointer to current directory name
lpStartupInfo: STARTUPINFO;// pointer to STARTUPINFO
sa: TSecurityAttributes;
procedure Error(Str: string);
begin
MessageBox(0,pchar(str),pchar("Error"),MB_OK);
Abort;
end;
begin
sa.nLength := sizeof(sa);
sa.bInheritHandle := TRUE;
sa.lpSecurityDescriptor := nil;
if( not CreatePipe(
Pipes.hIn_Read, // address of variable for read handle
Pipes.hIn_Write, // address of variable for write handle
@sa, // pointer to security attributes
1024) ) then Error(ErPipe);
if( not CreatePipe(
Pipes.hOut_Read, // address of variable for read handle
Pipes.hOut_Write, // address of variable for write handle
@sa, // pointer to security attributes
0) ) then Error(ErPipe);
if( not CreatePipe(
Pipes.hEr_Read, // address of variable for read handle
Pipes.hEr_Write, // address of variable for write handle
@sa, // pointer to security attributes
0) ) then Error(ErPipe);
bInheritHandles := true;
dwCreationFlags := CREATE_NEW_CONSOLE or IDLE_PRIORITY_CLASS;
lpCurrentDirectory := GetCurrentDir;
ZeroMemory(@lpStartupInfo, sizeof(lpStartupInfo));
lpStartupInfo.cb := sizeof(lpStartupInfo);
lpStartupInfo.hStdError := Pipes.hEr_Write;
lpStartupInfo.hStdInput := Pipes.hIn_Read;
lpStartupInfo.hStdOutput := Pipes.hOut_Write;
lpStartupInfo.dwX := CW_USEDEFAULT;
lpStartupInfo.dwY := CW_USEDEFAULT;
lpStartupInfo.dwXSize := CW_USEDEFAULT;
lpStartupInfo.dwYSize := CW_USEDEFAULT;
lpStartupInfo.dwFlags := STARTF_USESTDHANDLES or STARTF_USESHOWWINDOW or STARTF_USEPOSITION;
lpStartupInfo.wShowWindow := SW_HIDE;
ZeroMemory(@lpProcessInformation, sizeof(lpProcessInformation));
if( not CreateProcess(
nil, // pointer to name of executable module
pchar(lpCommandLine), // pointer to command line string
nil, // pointer to process security attributes
nil, // pointer to thread security attributes
bInheritHandles, // handle inheritance flag
dwCreationFlags, // creation flags
nil, // pointer to new environment block
nil{pchar(lpCurrentDirectory)}, // pointer to current directory name
lpStartupInfo, // pointer to STARTUPINFO
lpProcessInformation // pointer to PROCESS_INFORMATION
) ) then Error(ErProcess);
end;
procedure Tfrm_Console.FormCreate(Sender: TObject);
begin
ExecConsole("cmd.exe", pi);
ReadThread := TReadThread.Create(true);
ReadThread.Priority := tpIdle;
ReadThread.Resume;
end;
procedure Tfrm_Console.FormDestroy(Sender: TObject);
begin
ReadThread.Terminate;
Send(Pipes.hOut_Write, "Exit");
ReadThread.Destroy;
GetExitCodeProcess(pi.hProcess, pExitCode);
TerminateProcess(pi.hProcess, pExitCode);
end;
procedure Tfrm_Console.Send(Handle: THandle; Text: string);
var
bytes:cardinal;
mem: pchar;
size: integer;
begin
size := Length(Text);
mem := allocmem(size+1);
try
CopyMemory(Mem, pchar(Text),size);
WriteFile(Handle, mem^ ,size,bytes,nil);
finally
FreeMem(Mem);
end;
end;
procedure Tfrm_Console.btn_sendClick(Sender: TObject);
begin
Send(Pipes.hIn_Write,WinToDos(ed_Send.Text) + #13#10);
end;
procedure Tfrm_Console.ed_sendKeyPress(Sender: TObject; var Key: Char);
begin
if(Key = #13) then btn_send.Click();
end;
← →
Tatianka (2004-12-30 17:42) [5]Сделай поиск глобальный по сайту по STDOUT, он вернет ссылку, где в качестве примера приведено задание, которые надо сделать.
Страницы: 1 вся ветка
Текущий архив: 2005.02.20;
Скачать: CL | DM;
Память: 0.48 MB
Время: 0.038 c