Получить консольный вывод в Delphi 2010
| Автор
| Сообщение |
 KVas
Новичок

Возраст: 46
Знак зодиака: 
Зарегистрирован: 26.08.2008
Сообщения: 17
|
|
|
Цитата |
|
Здравствуйте!
Задача далеко не новая, в нете полно примеров, но почему-то у меня не получается полноценно запустить. Вот нагуглил примерчик
| delphi: | 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; procedure TForm1.Button1Click(Sender: TObject); var p,dp,s:string; F: TextFile; y:cardinal; begin GetDir(0, dp); s:='ping localhost'; p:=dp+'\tmp.cmd'; AssignFile(F, p); ReWrite(F); WriteLn(F,s); CloseFile(F); Memo1.Text:=GetDosOutput(p,dp,y); end;
|
вроде компилится и работает, но в результате выдает кваратики вместо букв.
Что может быть причиной и как это поправить. |
|
| В начало |
|
 |
|
|
 |
 Gelios
Oracle-вый маньяк, Админ

Возраст: 37
Знак зодиака: 
Зарегистрирован: 10.03.2005
Сообщения: 6141
Откуда: Яблочный рай
|
|
|
Цитата |
|
попробуй все типы string, pchar, char заменить на ansistring, pansichar, ansichar _________________ нельзя давать всем всего, ибо всех много, а всего мало |
|
| В начало |
|
 |
 KVas
Новичок

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

Возраст: 46
Знак зодиака: 
Зарегистрирован: 26.08.2008
Сообщения: 17
|
|
|
Цитата |
|
Вот нашел полностью рабочий пример, вывод передается прямо в Мемо.
| delphi: | procedure ExecuteCmd(DosApp:String); const ReadBuffer = 2400; var Security : TSecurityAttributes; ReadPipe,WritePipe : THandle; start : TStartUpInfo; ProcessInfo : TProcessInformation; Buffer : PAnsiChar; BytesRead,Apprunning: DWord; p : string; F : TextFile; begin p:=dp+'\tmp.cmd'; AssignFile(F, p); ReWrite(F); WriteLn(F,DosApp); CloseFile(F); With Security do begin nlength := SizeOf(TSecurityAttributes); binherithandle := true; lpsecuritydescriptor := nil; end; if Createpipe (ReadPipe, WritePipe, @Security, 0) then begin Buffer := AllocMem(ReadBuffer + 1); FillChar(Start,Sizeof(Start),#0); start.cb := SizeOf(start); start.hStdOutput := WritePipe; start.hStdInput := ReadPipe; start.dwFlags := STARTF_USESTDHANDLES + STARTF_USESHOWWINDOW; start.wShowWindow := SW_HIDE; if CreateProcess(nil, PChar(P), @Security, @Security, true, NORMAL_PRIORITY_CLASS, nil, nil, start, ProcessInfo) then begin repeat Apprunning := WaitForSingleObject (ProcessInfo.hProcess,100); Application.ProcessMessages; until (Apprunning <> WAIT_TIMEOUT); Repeat BytesRead := 0; ReadFile(ReadPipe,Buffer[0], ReadBuffer,BytesRead,nil); Buffer[BytesRead]:= #0; OemToAnsi(PAnsiChar(Buffer),PAnsiChar(Buffer)); fmMain.Memo.Text := fmMain.Memo.text + String(Buffer); until (BytesRead < ReadBuffer); end; FreeMem(Buffer); CloseHandle(ProcessInfo.hProcess); CloseHandle(ProcessInfo.hThread); CloseHandle(ReadPipe); CloseHandle(WritePipe); end; DeleteFile(P); end;
|
Спасибо за консультации. |
|
| В начало |
|
 |
|
Новая тема
Ответить
Печать
|
Вы можете начинать темы Вы можете отвечать на сообщения Вы не можете редактировать свои сообщения Вы не можете удалять свои сообщения Вы не можете голосовать в опросах Вы не можете присоединять файлы в этом форуме Вы можете скачивать файлы в этом форуме
|
|