Chertenok.ru - все о программировании
Вход  |  Регистрация  |  Поиск 
Праздник
Завтра :

День славянской письменности и культуры


Получить консольный вывод в Delphi 2010


Новая тема  Ответить  Печать Предыдущая тема  Следующая тема
Автор Сообщение
Пол:Муж KVas
Новичок


Возраст: 46
Знак зодиака: Скорпион
Зарегистрирован: 26.08.2008
Сообщения: 17

СообщениеЧт, 11-Авг-2011 16:22    Заголовок сообщения: Получить консольный вывод в Delphi 2010
Цитата

Здравствуйте!
Задача далеко не новая, в нете полно примеров, но почему-то у меня не получается полноценно запустить. Вот нагуглил примерчик
delphi:
  1.  
  2. Function GetDosOutput( const CommandLine, WorkDir: String;
  3.                       var ResultCode: Cardinal ): String;
  4. var StdOutPipeRead, StdOutPipeWrite: THandle;
  5.    SA                             : TSecurityAttributes;
  6.    SI                             : TStartupInfo;
  7.    PI                             : TProcessInformation;
  8.    WasOK                          : Boolean;
  9.    Buffer                         : array[0..255] of Char;
  10.    BytesRead                      : Cardinal;
  11.    Line                           : String;
  12. Begin
  13.    Application.ProcessMessages;
  14.    With SA do
  15.    Begin
  16.       nLength := SizeOf( SA );
  17.       bInheritHandle := True;
  18.       lpSecurityDescriptor := nil;
  19.    end;
  20.    // создаём пайп для перенаправления стандартного вывода
  21.    CreatePipe( StdOutPipeRead,  // дескриптор чтения
  22.                StdOutPipeWrite, // дескриптор записи
  23.                @SA,              // аттрибуты безопасности
  24.                0                // количество байт принятых для пайпа - 0 по умолчанию
  25.               );
  26.    try
  27.     // Создаём дочерний процесс, используя StdOutPipeWrite в качестве стандартного вывода,
  28.     // а так же проверяем, чтобы он не показывался на экране.
  29.     with SI do
  30.     Begin
  31.        FillChar( SI, SizeOf( SI ), 0 );
  32.        cb := SizeOf( SI );
  33.        dwFlags := STARTF_USESHOWWINDOW or STARTF_USESTDHANDLES;
  34.        wShowWindow := SW_HIDE; //не показывать окно
  35.        hStdInput := GetStdHandle( STD_INPUT_HANDLE ); // стандартный ввод не перенаправляем
  36.        hStdOutput := StdOutPipeWrite;
  37.        hStdError := StdOutPipeWrite;
  38.     end;
  39.  
  40.     // Запускаем компилятор из командной строки
  41.     //WorkDir := ExtractFilePath(CommandLine);
  42.     WasOK := CreateProcess( nil,
  43.                             PChar( CommandLine ),
  44.                             nil,
  45.                             nil,
  46.                             True,
  47.                             0,
  48.                             nil,
  49.                             PChar( WorkDir ),
  50.                             SI,
  51.                             PI );
  52.     // Теперь, когда дескриптор получен, для безопасности закрываем запись.
  53.     // Нам не нужно, чтобы произошло случайное чтение или запись.
  54.     CloseHandle( StdOutPipeWrite );
  55.     // если процесс может быть создан, то дескриптор, это его вывод
  56.     if not WasOK then
  57.      raise Exception.Create( 'Ошибка выполнения или компиляции: ' +
  58.             Chr( 10 ) + Chr( 13 ) + CommandLine )
  59.     else
  60.       try
  61.         // получаем весь вывод до тех пор, пока DOS-приложение не будет завершено
  62.         Line := '';
  63.         Repeat
  64.            // читаем блок символов (могут содержать возвраты каретки и переводы строки)
  65.            WasOK := ReadFile( StdOutPipeRead, Buffer, 255, BytesRead, nil );
  66.            // есть ли что-нибудь ещё для чтения?
  67.            if BytesRead > 0 then
  68.            Begin
  69.               // завершаем буфер PChar-ом
  70.               Buffer[BytesRead] := #0;
  71.               // добавляем буфер в общий вывод
  72.               Line := Line + Buffer;
  73.            end;
  74.            Application.ProcessMessages;
  75.         Until not WasOK or ( BytesRead = 0 );
  76.         // ждём, пока завершится консольное приложение
  77.         WaitForSingleObject( PI.hProcess, INFINITE );
  78.         ResultCode := 0;
  79.         GetExitCodeProcess( PI.hProcess, ResultCode );
  80.       finally
  81.         // Закрываем все оставшиеся дескрипторы
  82.         CloseHandle( PI.hThread );
  83.         CloseHandle( PI.hProcess );
  84.       end;
  85.    finally
  86.      Result := Line;
  87.      CloseHandle( StdOutPipeRead );
  88.  end;
  89. end;
  90.  
  91. procedure TForm1.Button1Click(Sender: TObject);
  92. var p,dp,s:string;
  93.     F: TextFile;
  94.     y:cardinal;
  95. begin
  96.   GetDir(0, dp);
  97.   s:='ping localhost';
  98.   p:=dp+'\tmp.cmd'; AssignFile(F, p); ReWrite(F);
  99.   WriteLn(F,s); CloseFile(F);
  100.   Memo1.Text:=GetDosOutput(p,dp,y);
  101. end;
  102.  


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

Что может быть причиной и как это поправить.
В начало
Посмотреть профиль Отправить личное сообщение
Пол:Муж Gelios
Oracle-вый маньяк, Админ


Возраст: 37
Знак зодиака: Водолей
Зарегистрирован: 10.03.2005
Сообщения: 6141
Откуда: Яблочный рай
СообщениеЧт, 11-Авг-2011 18:16 
Цитата

попробуй все типы string, pchar, char заменить на ansistring, pansichar, ansichar
_________________
нельзя давать всем всего, ибо всех много, а всего мало
В начало
Посмотреть профиль Отправить личное сообщение
Пол:Муж KVas
Новичок


Возраст: 46
Знак зодиака: Скорпион
Зарегистрирован: 26.08.2008
Сообщения: 17

СообщениеПт, 12-Авг-2011 8:11 
Цитата

to Gelios
Спасибо
Buffer: array[0..255] of AnsiChar;
Line : AnsiString;
пошептало, только текст теперь в DOS-кодировке и отображается крякозябрами. Счас погуглю эту проблемку самостоятельно.
Еще раз большое человеческое спасибо.
В начало
Посмотреть профиль Отправить личное сообщение
Пол:Муж KVas
Новичок


Возраст: 46
Знак зодиака: Скорпион
Зарегистрирован: 26.08.2008
Сообщения: 17

СообщениеЧт, 18-Авг-2011 11:49 
Цитата

Вот нашел полностью рабочий пример, вывод передается прямо в Мемо.
delphi:
  1.  
  2.  
  3. procedure ExecuteCmd(DosApp:String);
  4. const
  5.     ReadBuffer = 2400;
  6. var
  7.   Security            : TSecurityAttributes;
  8.   ReadPipe,WritePipe  : THandle;
  9.   start               : TStartUpInfo;
  10.   ProcessInfo         : TProcessInformation;
  11.   Buffer              : PAnsiChar;
  12.   BytesRead,Apprunning: DWord;
  13.   p                   : string;
  14.   F                   : TextFile;
  15. begin
  16.   p:=dp+'\tmp.cmd'; AssignFile(F, p); ReWrite(F);
  17.   WriteLn(F,DosApp); CloseFile(F);
  18.   With Security do begin
  19.     nlength              := SizeOf(TSecurityAttributes);
  20.     binherithandle       := true;
  21.     lpsecuritydescriptor := nil;
  22.   end;
  23.   if Createpipe (ReadPipe, WritePipe, @Security, 0)
  24.   then begin
  25.     Buffer  := AllocMem(ReadBuffer + 1);
  26.     FillChar(Start,Sizeof(Start),#0);
  27.     start.cb          := SizeOf(start);
  28.     start.hStdOutput  := WritePipe;
  29.     start.hStdInput   := ReadPipe;
  30.     start.dwFlags     := STARTF_USESTDHANDLES +
  31.                          STARTF_USESHOWWINDOW;
  32.     start.wShowWindow := SW_HIDE;
  33.  
  34.     if CreateProcess(nil,
  35.             PChar(P),
  36.             @Security,
  37.             @Security,
  38.             true,
  39.             NORMAL_PRIORITY_CLASS,
  40.             nil,
  41.             nil,
  42.             start,
  43.             ProcessInfo)
  44.     then begin
  45.       repeat
  46.        Apprunning := WaitForSingleObject
  47.                     (ProcessInfo.hProcess,100);
  48.        Application.ProcessMessages;
  49.       until (Apprunning <> WAIT_TIMEOUT);
  50.       Repeat
  51.         BytesRead := 0;
  52.         ReadFile(ReadPipe,Buffer[0],
  53.                 ReadBuffer,BytesRead,nil);
  54.         Buffer[BytesRead]:= #0;
  55.         OemToAnsi(PAnsiChar(Buffer),PAnsiChar(Buffer));
  56.         fmMain.Memo.Text := fmMain.Memo.text + String(Buffer);
  57.       until (BytesRead < ReadBuffer);
  58.     end;
  59.     FreeMem(Buffer);
  60.     CloseHandle(ProcessInfo.hProcess);
  61.     CloseHandle(ProcessInfo.hThread);
  62.     CloseHandle(ReadPipe);
  63.     CloseHandle(WritePipe);
  64.   end;
  65.   DeleteFile(P);
  66. end;
  67.  

Спасибо за консультации.
В начало
Посмотреть профиль Отправить личное сообщение
Показать сообщения:   
Страница 1 из 1
Перейти:  
Новая тема  Ответить  Печать

Вы можете начинать темы
Вы можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете голосовать в опросах
Вы не можете присоединять файлы в этом форуме
Вы можете скачивать файлы в этом форуме
хостинг от .masterhost 
Rambler's Top100