Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 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.49 MB
Время: 0.031 c
1-1107819015
KOLIG
2005-02-08 02:30
2005.02.20
проблема с вставлением текста в RichEdit


14-1105102343
zt50
2005-01-07 15:52
2005.02.20
Нужны толковые люди.


3-1106419687
stud1
2005-01-22 21:48
2005.02.20
Компоненты ввода даты в базу данных


1-1107120746
Homa_Programer
2005-01-31 00:32
2005.02.20
как правильно создать в run-time TabSheet и на нем RichEdit?


4-1104765228
Error202
2005-01-03 18:13
2005.02.20
Передача данных из IE в приложение