Модераторы: Snowy, bartram, MetalFan, bems, Poseidon, Riply
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Как принять сообщение WinRAR c StdErr 
:(
    Опции темы
kucik
  Дата 12.5.2005, 01:00 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 14
Регистрация: 22.4.2004
Где: Russia, Murmansk

Репутация: нет
Всего: нет



В RAR'e есть такой ключик -ierr - перенаправление всех сообщений на стандартное устройство ошибки.
Как принять все эти сообщения?
Прочитал эту тему Запуск внешнего приложения, и слежение за тем, что оно пишет в консоли, но моя проблемма немного в другом (на мой взгляд), т.к. в моём случае информация уже выводится на стандартное устройство ошибки!?
Попробовал такой вариант:
Код

 ...
  if Result then
    begin
      Line := '';
      REPEAT
        Result := ReadFile(StartInfo.hStdError, Buffer, 255, BytesRead, nil);
        if BytesRead > 0 then
          begin
              // завершаем буфер PChar-ом
            Buffer[BytesRead] := #0;
              // добавляем буфер в общий вывод
            Line := Line + Buffer;
          end;
      UNTIL NOT Result or (BytesRead = 0);

      while WaitforSingleObject(ProcInfo.hProcess,200)=WAIT_TIMEOUT do
        Application.ProcessMessages;
...

... он не проходит, BytesRead всегда 0
Thanks!

PM MAIL ICQ   Вверх
Alex
Дата 12.5.2005, 07:07 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Экс. модератор
Сообщений: 4147
Регистрация: 25.3.2002
Где: Москва

Репутация: 6
Всего: 162



Не проверял, но должно работать:
Код

function GetDosOutput(const CommandLine:string): string;
var
  SA: TSecurityAttributes;
  SI: TStartupInfo;
  PI: TProcessInformation;
  StdOutPipeRead, StdOutPipeWrite: THandle;
  WasOK: Boolean;
  Buffer: array[0..255] of Char;
  BytesRead: Cardinal;
  WorkDir, Line: String;
begin
  Application.ProcessMessages;
  with SA do
  begin
    nLength := SizeOf(SA);
    bInheritHandle := True;
    lpSecurityDescriptor := nil;
  end;
  // создаём пайп для перенаправления стандартного вывода
  CreatePipe(StdOutPipeRead,  // дескриптор чтения
             StdOutPipeWrite, // дескриптор записи
             @SA,              // аттрибуты безопасности
             0                // количество байт принятых для пайпа - 0 по умолчанию
             );
  try
    // Создаём дочерний процесс, используя StdOutPipeWrite в качестве стандартного вывода,
    // а так же проверяем, чтобы он не показывался на экране.
    with SI do
    begin
      FillChar(SI, SizeOf(SI), 0);
      cb := SizeOf(SI);
      dwFlags := STARTF_USESHOWWINDOW or STARTF_USESTDHANDLES;
      wShowWindow := SW_HIDE;
      hStdInput := GetStdHandle(STD_INPUT_HANDLE); // стандартный ввод не перенаправляем
      hStdOutput := GetStdHandle(STD_OUTPUT_HANDLE); // стандартный вывод не перенаправляем
      hStdError := StdOutPipeWrite;
    end;

    // Запускаем компилятор из командной строки
    WorkDir := ExtractFilePath(CommandLine);
    WasOK := CreateProcess(nil, PChar(CommandLine), nil, nil, True, 0, nil, PChar(WorkDir), SI, PI);

    // Теперь, когда дескриптор получен, для безопасности закрываем запись. 
    // Нам не нужно, чтобы произошло случайное чтение или запись. 
    CloseHandle(StdOutPipeWrite);  
    // если процесс может быть создан, то дескриптор, это его вывод
    if not WasOK then 
      raise Exception.Create('Could not execute command line!') 
    else 
      try 
        // получаем весь вывод до тех пор, пока DOS-приложение не будет завершено
        Line := ''; 
        repeat 
          // читаем блок символов (могут содержать возвраты каретки и переводы строки) 
          WasOK := ReadFile(StdOutPipeRead, Buffer, 255, BytesRead, nil); 

          // есть ли что-нибудь ещё для чтения? 
          if BytesRead > 0 then 
          begin 
            // завершаем буфер PChar-ом 
            Buffer[BytesRead] := #0;
            // добавляем буфер в общий вывод 
            Line := Line + Buffer; 
          end; 
        until not WasOK or (BytesRead = 0); 
        // ждём, пока завершится консольное приложение
        WaitForSingleObject(PI.hProcess, INFINITE); 
      finally 
        // Закрываем все оставшиеся дескрипторы 
        CloseHandle(PI.hThread); 
        CloseHandle(PI.hProcess);
      end; 
  finally 
      result:=Line; 
      CloseHandle(StdOutPipeRead); 
  end;
end;



--------------------
Написать можно все - главное четко представлять, что ты хочешь получить в конце. 
PM Skype   Вверх
andrey_pst
Дата 12.5.2005, 07:42 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Awaiting Authorisation
Сообщений: 37
Регистрация: 24.4.2003
Где: Пермь

Репутация: нет
Всего: 1



Код

// архивирует файлы в архив WinRar (ver.2.7) и возвращает код возврата архиватора
function AddToRAR(RarVisible : boolean; RarDir, RarFileName, RarCommand, ArchiveName, FileNames, RarOptions : string) : integer;
var
  PChTmp   : PChar;  // командная строка
  ExitCode : dword;  // код возврата архиватора
  si : STARTUPINFO;
  pi : PROCESS_INFORMATION;
  ErrorWavFileName : PChar;
begin
  PChTmp := PChar(RarDir + RarFileName + ' ' + RarCommand + ' ' + ArchiveName +  ' ' + FileNames + ' ' + RarOptions);
  ZeroMemory(@si, sizeof(si));
  si.cb := SizeOf(si);  // размер структуры в байтах
  si.dwFlags := STARTF_USESHOWWINDOW;
  if RarVisible then
    si.wShowWindow := SW_SHOWNOACTIVATE  // окно видимо и неактивно
  else
    si.wShowWindow := SW_HIDE;           // окно невидимо
  if not CreateProcess(nil, PChTmp, nil, nil, false, 0, nil, nil, si, pi) then  // запустим rar.exe
    ExitCode := 999  // не удалось создать процесс
  else
  begin
    WaitForSingleObject(pi.hProcess, INFINITE);  // ждем окончания процесса
    GetExitCodeProcess(pi.hProcess, ExitCode);   // получаем код возврата
  end;
  CloseHandle(pi.hProcess);
  CloseHandle(pi.hThread);

  result := ExitCode;
end;

PM MAIL   Вверх
kucik
  Дата 14.5.2005, 02:33 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 14
Регистрация: 22.4.2004
Где: Russia, Murmansk

Репутация: нет
Всего: нет



smile
Уважаемый Alex, я же написал что читал данную Тобой ссылку (Тему .. и даже её привёл!!) ... и там приведённый тобой код есть, только вот незадача - он не работает тозе! smile может конечно я что-то коряво делаю ... да и пример который я сам написал по аналогии должен был бы тоже тогда работать! smile

2 andrey_pst:
С кодом возврата всё понятно! ... Непонятно как прочитать всё что WinRAR выводит в консоль ... а выводить он это может на стандартное устройство ошибки ... следовательно оттудова нам надо это и прочитать!!!
=>
Если
StartInfo: TStartupInfo;
то, по идее
StartInfo.hStdError
- и есть искомое стандартное устройство ошибки .. но не тут то было!
В Result := ReadFile(StartInfo.hStdError, Buffer, 255, BytesRead, nil); пусто!!!
и BytesRead = 0, т.е. ничего не прочитанно smile
хотя Buffer: array[0..255] of Char; если его посмотреть, то он что-то содержит .. (но так как это массив, причём нигде не "обнуляемый", то он просто может содержать всякую чушь!!)
Помогите плиззз!!!
smile
PM MAIL ICQ   Вверх
Alix
Дата 14.5.2005, 07:11 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


L45
**


Профиль
Группа: Участник
Сообщений: 581
Регистрация: 4.5.2005
Где: Pskov/Spb

Репутация: 3
Всего: 23



Может я не прав и мое представление о мире устарело, но вроде все что выводиться в stderr выводиться только на экран и никуда более... И поток этот перенаправлять нельзя...
К примеру, если вы запустите что-то так: smth.exe > t.txt, то все запишется в файл t.txt. Но! Если это прога выводит что-то в stderr, то оно в t.txt не попадет, но с гарантией попадет на экран.
Или я не прав?


--------------------
Знание только тогда знание, когда оно приобретено усилиями своей мысли, а не памятью (с) Л. Толстой
High tech. Low live. (с) Gardner Dozois
PM MAIL ICQ Skype   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "Delphi: WinAPI и системное программирование"
Snowybartram
MetalFanbems
PoseidonRrader
Riply

Запрещено:

1. Публиковать ссылки на вскрытые компоненты

2. Обсуждать взлом компонентов и делиться вскрытыми компонентами

  • Литературу по Delphi обсуждаем здесь
  • Действия модераторов можно обсудить здесь
  • С просьбами о написании курсовой, реферата и т.п. обращаться сюда
  • Вопросы по реализации алгоритмов рассматриваются здесь
  • 90% ответов на свои вопросы можно найти в DRKB (Delphi Russian Knowledge Base) - крупнейшем в рунете сборнике материалов по Дельфи
  • 99% ответов по WinAPI можно найти в MSDN Library, оставшиеся 1% здесь

Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Snowy, bartram, MetalFan, bems, Poseidon, Rrader, Riply.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Delphi: WinAPI и системное программирование | Следующая тема »


 




[ Время генерации скрипта: 0.0456 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.