Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2006.05.07;
Скачать: CL | DM;

Вниз

запуск приложений и получение результатов   Найти похожие ветки 

 
ExE ©   (2006-02-16 10:26) [0]

Здравстуйте.
Подкажите пожалуйста вот такую вешь...
Есть приложение, кот. вызывает другое консольное приложение CVS.exe. Это CVS.exe может возвращать результаты (например, ошибку).
Вопрос как их считать из программы на Delphi ?!?

Замучился уже подскажите плиз


 
kaZaNoVa ©   (2006-02-16 10:29) [1]

запуск через CreateProcess


 
ExE ©   (2006-02-16 10:31) [2]

CreateProcess (
        nil,
        pchar(""cvs.exe" "checkout" "
                     +""-d" "d:\pesok" "
                     +""-r" "HEAD" "-N" "
                     +"""+ExctractFileNameNoDir(ParamStr(i))+"""),
        nil,
        nil,
        false,
        NORMAL_PRIORITY_CLASS,
        nil,
        nil,
        lpStartupInfo,
        lpProcessInformation );
      WaitForSingleObject (lpProcessInformation.hProcess,INFINITE);

А где результаты работы CVS.exe прочитать?


 
BiN ©   (2006-02-16 10:35) [3]

Код завершения процесса можно получить с помощью GetExitCodeProcess.
Другой вопрос, как получить описатель процесса CVS.exe.
Если приложение-загрузчик не предоставляет никаких механизмов контроля и взаимодействия, то как крайний случай можно предложить перехватывать CreateProcess в 9x/me системах и NtCreateProcess в NT-линейке.


 
ExE ©   (2006-02-16 10:44) [4]

Да, код возврата тоже вешь нужная, но я хочу получить результаты работы этого КОНСОЛЬНОГО приложения...
Ну к примеру.. командная строка..
"
D:\>cvs.exe -parametrs
-----------
revision 1.3
result = 01
-----------
revision 1.4
result = 02
"

Как прочитать в программе эти revision, result??


 
BiN ©   (2006-02-16 11:09) [5]


> ExE ©   (16.02.06 10:44) [4]
>
> Да, код возврата тоже вешь нужная, но я хочу получить результаты
> работы этого КОНСОЛЬНОГО приложения...
> Ну к примеру.. командная строка..
> "
> D:\>cvs.exe -parametrs
> -----------
> revision 1.3
> result = 01
> -----------
> revision 1.4
> result = 02
> "
>
> Как прочитать в программе эти revision, result??


Перенаправить вывод консольного приложения можно, задав в качестве стандартного описателя вывода (hStdOutput и hStdError в STARTUPINFO) описатель заранее созданного канала, из которого впоследствии и считываются данные.
Вот пример навскидку
http://kladovka.net.ru/delphibase/?action=viewfunc&topic=winappctrl&id=10317


 
BiN ©   (2006-02-16 11:12) [6]

Только будь готов столкнуться с проблемой, когда некоторые консольные приложения создают дополнительные экранные буферы вывода (например telnet). В таких случаях данный подход неприменим.


 
xShadow ©   (2006-02-16 11:12) [7]


> Как прочитать в программе эти revision, result??

Для этого нужно получить StdOut приложения и выполнить его разбор.
Function GetDosOutput( const CommandLine, WorkDir: String;
                      var ResultCode: Cardinal ): String;
var StdOutPipeRead, StdOutPipeWrite: THandle;
   SA                             : TSecurityAttributes;
   SI                             : TStartupInfo;
   PI                             : TProcessInformation;
   WasOK                          : Boolean;
   Buffer                         : array[0..255] of Char;
   BytesRead                      : Cardinal;
   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 := StdOutPipeWrite;
       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( "Ошибка выполнения или компиляции: " +
            Chr( 10 ) + Chr( 13 ) + CommandLine )
    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;
           Application.ProcessMessages;
        Until not WasOK or ( BytesRead = 0 );
        // ждём, пока завершится консольное приложение
        WaitForSingleObject( PI.hProcess, INFINITE );
        ResultCode := 0;
        GetExitCodeProcess( PI.hProcess, ResultCode );
      finally
        // Закрываем все оставшиеся дескрипторы
        CloseHandle( PI.hThread );
        CloseHandle( PI.hProcess );
      end;
   finally
     Result := Line;
     CloseHandle( StdOutPipeRead );
 end;
end;


 
ExE ©   (2006-02-16 11:45) [8]

xShadow
БОЛЬШОЕ СПАСИБО
Отличный пример

BiN
Спасибо за ссылку

Всем огромное спасибо, спасли!



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

Текущий архив: 2006.05.07;
Скачать: CL | DM;

Наверх




Память: 0.5 MB
Время: 0.041 c
3-1142406478
Stanislav
2006-03-15 10:07
2006.05.07
Сохранение *.udl файла


2-1145495035
humanlife
2006-04-20 05:03
2006.05.07
radiogrup


2-1145386684
Инна
2006-04-18 22:58
2006.05.07
Биты


2-1145415282
Лёха
2006-04-19 06:54
2006.05.07
Сделать крестик нерабочим


15-1145023037
iamdanil
2006-04-14 17:57
2006.05.07
Глюк винды (фотка)