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

Вниз

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

 
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 вся ветка

Форум: "WinAPI";
Текущий архив: 2006.05.07;
Скачать: [xml.tar.bz2];

Наверх





Память: 0.49 MB
Время: 0.012 c
3-1142515998
jeka_t
2006-03-16 16:33
2006.05.07
Можно ли с нескольких полей сделать одно поле?


15-1144909345
DelphiN!
2006-04-13 10:22
2006.05.07
IntToStr в C#


15-1144848011
Толян
2006-04-12 17:20
2006.05.07
MySQL


2-1145603620
makar
2006-04-21 11:13
2006.05.07
TRichEdit


3-1142415011
AlexeyMir
2006-03-15 12:30
2006.05.07
Как выделить права добавленному пользователю на все таблицы в IB?





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
Английский Французский Немецкий Итальянский Португальский Русский Испанский