Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Основная";
Текущий архив: 2006.09.03;
Скачать: [xml.tar.bz2];

Вниз

Перенаправление stdout & stdin консольного приложения   Найти похожие ветки 

 
pasha_golub ©   (2006-07-20 13:27) [0]

Моя программа - фронтэнд для консоли. Задача: запустить с нужными параметрами, передать пароль и вернуть вывод.

Есть код, который работает с предыдущей версией сторонней консольной программы, но не работает с последней версией. Хотя видимых различий не нашел.

Процесс запускается. Выводит "Password:" и ждет ввода. Но в моей программе исполнение ждет чтения:

          // read block of data
          WasOK := ReadFile( StdOutPipeRead, Buffer, 1023, BytesRead, nil );


Подскажите, кто что сможет, пожалуйста.


Function GetConsoleOutput( CommandLine, Pass, ResName: String; var ResultCode: Cardinal ): String;
var
   //process launch and in/out stuff
   StdOutPipeRead,
   StdOutPipeWrite,
   StdInPipeRead,
   StdInPipeWrite: THandle;
   SA            : TSecurityAttributes;
   SI            : TStartupInfo;
   PI            : TProcessInformation;
   WasOK         : Boolean;
   Buffer        : array[0..1023] of Char;
   BytesRead     : Cardinal;
   Line          : String;
   Written       : DWORD;
   Passed        : boolean;
   nb, i: Cardinal;
   RS: TResourceStream;
Begin
  With SA do
  Begin
     nLength := SizeOf( SA );
     bInheritHandle := True;
     lpSecurityDescriptor := nil;
  end;
  CreatePipe( StdOutPipeRead,
              StdOutPipeWrite,
              @SA,
              0           );
  CreatePipe( StdInPipeRead,
              StdInPipeWrite,
              @SA,
              0           );
  try
   with SI do
   Begin
      FillChar( SI, SizeOf( SI ), 0 );
      cb := SizeOf( SI );
      dwFlags := STARTF_USESHOWWINDOW or STARTF_USESTDHANDLES;
      wShowWindow := SW_HIDE or SW_SHOWMINNOACTIVE;
      hStdInput := StdInPipeRead;
      hStdOutput := StdOutPipeWrite;
      hStdError := StdOutPipeWrite;
   end;
   Passed := false;

   RS := TResourceStream.Create(HInstance,ResName,Pchar("EXEFILE"));
    try
   RS.SaveToFile(ResName+".exe");
   CommandLine := Format(CommandLine,[ResName+".exe"]);
   WasOK := CreateProcess( nil,
                     PChar(Commandline),
                     nil,
                     nil,
                     True,
                     0,
                     nil,
                     nil,
                     SI,
                     PI );
    finally
   RS.Free;
    end;

   CloseHandle( StdOutPipeWrite );
   CloseHandle( StdInPipeRead );
   if not WasOK then
    raise Exception.Create( "Can""t start process: "#10#13 +
            CommandLine )
   else
     try
       Line := "";
       Repeat
          // read block of data
          WasOK := ReadFile( StdOutPipeRead, Buffer, 1023, BytesRead, nil );
          // is there anything to read
          if BytesRead > 0 then
          Begin
             Buffer[BytesRead] := #0;
             // add buffer
             Line := Line + Buffer;
          end;
         If not Passed AND
            (Pos("PASSWORD:",AnsiUpperCase(Line)) > 0) then
           begin
             Line := StringReplace(Line,"password:","",[rfIgnoreCase]);
             Pass := Pass + #13#10; //add carriage return
             WasOk := WriteFile(StdinPipeWrite,Pass[1],length(Pass),Written,nil);
             Passed := true; //passed authorization
           end;
       Until not WasOK or ( BytesRead = 0 );
       // wait console
       WaitForSingleObject( pi.hProcess, INFINITE );
       ResultCode := 0;
       GetExitCodeProcess( pi.hProcess, ResultCode );
     finally
       // close descriptors
       CloseHandle( PI.hThread );
       CloseHandle( pi.hProcess );
     end;
  finally
    Result := Line;
    CloseHandle( StdOutPipeRead );
    CloseHandle( StdInPipeWrite );
    SysUtils.DeleteFile(ResName+".exe");
end;
end;


 
pasha_golub ©   (2006-07-20 13:29) [1]

Ой, мама, промахнулся разделом. Извините.


 
Slym ©   (2006-07-20 13:45) [2]

TOverlapped тебе в подарок


 
pasha_golub ©   (2006-07-20 14:29) [3]


> Slym ©   (20.07.06 13:45) [2]
>
> TOverlapped тебе в подарок
>

Спасибо за подарок. Деталей бы хотелось. Их есть у вас?


 
Игорь Шевченко ©   (2006-07-20 14:35) [4]


> Есть код, который работает с предыдущей версией сторонней
> консольной программы, но не работает с последней версией.
>  Хотя видимых различий не нашел.


Я извиняюсь, а новая версия точно работает через стандартные Handles, а не делает внутри себя что-то вроде AllocConsole и т.п. ?


 
pasha_golub ©   (2006-07-20 15:55) [5]


> Игорь Шевченко ©   (20.07.06 14:35) [4]


>
> Я извиняюсь, а новая версия точно работает через стандартные
> Handles, а не делает внутри себя что-то вроде AllocConsole
> и т.п. ?
>

Думал об этом. Попробую узнать у авторов. Спасибо


 
Slym ©   (2006-07-21 04:43) [6]

pasha_golub ©   (20.07.06 14:29) [3]
Деталей бы хотелось. Их есть у вас?

Чтение с таймаутом, выдрано из Scktcomp.pas, но применимо для файлов и пр. хендлов:
while true do
Читаешь StdIn(100мсеков)
пишешь StdOut
procedure ReadBuffer(ASocket:TSocket;var Buffer;Count:Longint;ATimeout:Longint=0);
var
 Overlapped: TOverlapped;
 ErrorCode,Result: Integer;
begin
 if ATimeout=0 then ATimeout:=DefTimeout;
 FillChar(OVerlapped,SizeOf(Overlapped),0);
 Overlapped.hEvent:=CreateEvent(nil,True,False,"");
 try
   if not ReadFile(ASocket, Buffer, Count, DWORD(Result),
     @Overlapped) and (GetLastError <> ERROR_IO_PENDING) then
   begin
     ErrorCode := GetLastError;
     raise ESocketError.CreateResFmt(@sSocketIOError, [sSocketRead, ErrorCode,
       SysErrorMessage(ErrorCode)]);
   end;
   if WaitForSingleObject(Overlapped.hEvent, ATimeout)<>WAIT_OBJECT_0 then
     Result := 0
   else
     GetOverlappedResult(ASocket, Overlapped, DWORD(Result), False);
 finally
   CloseHandle(Overlapped.hEvent);
 end;
end;

procedure WriteBuffer(ASocket:TSocket; const Buffer; Count: Longint;ATimeout:Longint=0);
var
 Overlapped: TOverlapped;
 ErrorCode,Result: Integer;
begin
 if ATimeout=0 then ATimeout:=DefTimeout;
 FillChar(OVerlapped,SizeOf(Overlapped),0);
 Overlapped.hEvent:=CreateEvent(nil,True,False,"");
 try
   if not WriteFile(ASocket, Buffer, Count, DWORD(Result),
     @Overlapped) and (GetLastError <> ERROR_IO_PENDING) then
   begin
     ErrorCode := GetLastError;
     raise ESocketError.CreateResFmt(@sSocketIOError, [sSocketWrite, ErrorCode,
       SysErrorMessage(ErrorCode)]);
   end;
   if WaitForSingleObject(Overlapped.hEvent, ATimeout)<>WAIT_OBJECT_0 then
     Result := 0
   else GetOverlappedResult(ASocket, Overlapped, DWORD(Result), False);
 finally
   CloseHandle(Overlapped.hEvent);
 end;
end;


 
RUNaum ©   (2006-07-21 07:19) [7]

Игорь Шевченко ©   (20.07.06 14:35) [4]
кстати, а как быть в случаях подобных AllocConsole, к примеру?


 
Игорь Шевченко ©   (2006-07-21 10:16) [8]

RUNaum ©   (21.07.06 07:19) [7]

А вроде никак...


 
pasha_golub ©   (2006-07-21 17:58) [9]


> Slym ©   (21.07.06 04:43) [6]

Спасибо попробую.

Раскопал библиотеку wxWidgets. Реализовано вроде так же как и у меня, но с некоторыми отстпуплениями. Кому интересно могу сюда выложить код.


 
pasha_golub ©   (2006-07-24 12:14) [10]


> Slym ©   (21.07.06 04:43) [6]

В хелпе написано:

Parameters

hFile

Identifies the file, named pipe, or communications device.


У меня anonymous pipe. Будет ли пригоден данный метод?


 
pasha_golub ©   (2006-07-24 12:30) [11]

Судя по всему, что нет. Вылетает ошибка.



Страницы: 1 вся ветка

Форум: "Основная";
Текущий архив: 2006.09.03;
Скачать: [xml.tar.bz2];

Наверх





Память: 0.49 MB
Время: 0.043 c
15-1155461333
Чемульпо
2006-08-13 13:28
2006.09.03
Помогите плиз!


15-1154692059
Сергей М.
2006-08-04 15:47
2006.09.03
А.Мисин... "минус" ..


2-1155419712
ronyn
2006-08-13 01:55
2006.09.03
pchar pansichar


15-1155297927
ArtemESC
2006-08-11 16:05
2006.09.03
Пытался установить 4 диска Брокгаузъ и Ефронъ...


3-1151048150
zdm
2006-06-23 11:35
2006.09.03
FASTReport нумерация полей





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский