![]() |
|
|
|||||||
| Регистрация | << Правила форума >> | FAQ | Пользователи | Календарь | Поиск | Сообщения за сегодня | Все разделы прочитаны |
![]() |
|
|
Опции темы | Поиск в этой теме | Опции просмотра |
|
|
|
#1
|
|||
|
|||
|
Добрый вечер. Не посылайте в поиск ибо весь день занимался поиском и честное слово копипастом но так ничего и не вышло. Нет дело не в копипасте что куда подставить и дописать я в курсе...
И так вопрос: Есть консольное приложение в котором появляется переодически текст и этот текст нужно вывести в memo1. все известные процедуры: GetDosOutput, RunDosInMemo, dos2win и тд не помогли(( Привожу пример использования GetDosOutput Код:
function GetDosOutput(const CommandLine,Parametrs: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 := StdOutPipeWrite;
hStdError := StdOutPipeWrite;
end;
// Запускаем компилятор из командной строки
WorkDir := ExtractFilePath(CommandLine);
WasOK := CreateProcess(nil,
PChar(CommandLine+' '+Parametrs),
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
Application.ProcessMessages;
// читаем блок символов (могут содержать возвраты каретки и переводы строки)
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:= utf8toansi(Line); // перекодируем UTF-8 в ANSI
CloseHandle(StdOutPipeRead);
end;
end;Код:
procedure TForm1.Button1Click(Sender: TObject); var dir: pansichar; begin Memo1.Clear; begin dir:= Pansichar(extractfilepath(paramstr(0))); memo1.Lines.Add( trim(GetDosOutput(dir+'1.bat', ''))); end; end; в батнике следующий текст: zbarcam.exe >rec.txt Запускается консоль в которой показывает текст распознаного QR кода, а затем появляется окно с изображением с web камеры. если можно обойтись без батника то тоже буду очень признателен, если поделитесь кодом... |
|
#2
|
|||
|
|||
|
Поправочка: Запускаю программу она зависат подношу qr код он распознаёт но в memo1 не выводит после закрытия окна Zbarcam.exe в memo1 появляется распознаный текст...
|
|
#3
|
||||
|
||||
|
А мне почему-то копипаста помогла:
Код:
procedure TfrmAvrGui.StartAvrDude(StartStr: Widestring);
var
si: STARTUPINFO;
sa: SECURITY_ATTRIBUTES;
sd: SECURITY_DESCRIPTOR; // структура security для пайпов
pri: PROCESS_INFORMATION;
texit: DWORD; // код завершения процесса
bread: DWORD; // кол-во прочитанных байт
avail: DWORD; // кол-во доступных байт
newstdin, newstdout, read_stdout, write_stdin: THandle;
buf: array [0 .. 1023] of AnsiChar;
begin
mmLog.Lines.Add('');
if not WT.Stop then
begin
mmLog.Lines.Add('*************************************');
mmLog.Lines.Add('AvrDude уже запущен!');
mmLog.Lines.Add('*************************************');
exit;
end;
WT.Stop := false;
InitializeSecurityDescriptor(@sd, SECURITY_DESCRIPTOR_REVISION);
SetSecurityDescriptorDacl(@sd, true, nil, false);
sa.lpSecurityDescriptor := @sd;
sa.nLength := SizeOf(SECURITY_ATTRIBUTES);
sa.bInheritHandle := true; // разрешаем наследование дескрипторов
if not CreatePipe(newstdin, write_stdin, @sa, 0) then
begin
ShowMessage('Ошибка создания Pipe');
exit;
end;
if not CreatePipe(read_stdout, newstdout, @sa, 0) then
begin
CloseHandle(newstdin);
CloseHandle(write_stdin);
ShowMessage('Ошибка создания Pipe');
exit;
end;
GetStartupInfo(si);
si.dwFlags := STARTF_USESTDHANDLES or STARTF_USESHOWWINDOW;
si.wShowWindow := SW_HIDE;
si.hStdOutput := newstdout;
si.hStdError := newstdout; // подменяем дескрипторы для
si.hStdInput := newstdin; // дочернего процесса
if cbAvrDude.ItemIndex = 0 then
S := 'avrdudeStd.exe'
else if cbAvrDude.ItemIndex = 1 then
S := 'avrdudeFTBB.exe';
if not CreateAvrDudeProcess(S, StartStr, cbDisableBCT.Checked, si, pri) then
begin
ShowMessage('Ошибка при запуске AvrDude');
exit;
end;
AvrDudeID := pri.dwProcessId;
btnStop.Enabled := true;
Zeromemory(@buf[0], 1024);
texit := 0;
while true do
begin
Application.ProcessMessages;
PeekNamedPipe(read_stdout, @buf[0], 1023, @bread, @avail, NIL);
// Проверяем, есть ли данные для чтения в stdout
if (bread <> 0) then
begin
Zeromemory(@buf[0], 1024);
if (avail > 1023) then
begin
while (bread >= 1023) do
begin
ReadFile(read_stdout, buf, 1023, bread, NIL); // читаем из
mmLog.Lines.Add(buf); // пайпа stdout
Zeromemory(@buf[0], 1024);
end;
end
else
begin
ReadFile(read_stdout, buf, 1023, bread, NIL);
mmLog.Lines.Add(buf);
end;
end;
GetExitCodeProcess(pri.hProcess, texit); // пока дочерний процесс
if (texit <> STILL_ACTIVE) then // не закрыт
break;
sleep(10);
end;
WT.Stop := true;
btnStop.Enabled := false;
CloseHandle(pri.hThread);
CloseHandle(pri.hProcess);
CloseHandle(newstdin); // небольшая уборка за собой
CloseHandle(newstdout);
CloseHandle(read_stdout);
CloseHandle(write_stdin);
end;
Последний раз редактировалось Bargest, 26.05.2013 в 20:46. |
|
#4
|
|||
|
|||
|
Цитата:
Цитата:
Последний раз редактировалось M.A.D.M.A.N., 26.05.2013 в 21:11. |
|
#5
|
||||
|
||||
|
Пример - StartAvrDude('Exe.exe -param1 -param2')
![]() http://www.sources.ru/cpp/using_anonymous_pipes.shtml |
|
#6
|
|||
|
|||
|
Цитата:
Ругался сначало на TfrmAvrGui я поменял на TForm1 затем выдал ошибку на TfrmAvrGui.=>StartAvrDude<= я так понял нужно в приват или public обьявить что то... Но там в окне ещё куча ошибок: Код:
Build
[Error] Unit1.pas(33): Undeclared identifier: 'StartAvrDude'
[Error] Unit1.pas(33): ';' expected but '(' found
[Error] Unit1.pas(46): Undeclared identifier: 'mmLog'
[Error] Unit1.pas(46): Missing operator or semicolon
[Error] Unit1.pas(47): Undeclared identifier: 'WT'
[Error] Unit1.pas(49): Missing operator or semicolon
[Error] Unit1.pas(50): Missing operator or semicolon
[Error] Unit1.pas(51): Missing operator or semicolon
[Error] Unit1.pas(54): Missing operator or semicolon
[Error] Unit1.pas(81): Undeclared identifier: 'cbAvrDude'
[Error] Unit1.pas(83): 'THEN' expected but identifier 'ItemIndex' found
[Error] Unit1.pas(85): Undeclared identifier: 'CreateAvrDudeProcess'
[Error] Unit1.pas(85): Undeclared identifier: 'S'
[Error] Unit1.pas(85): Undeclared identifier: 'cbDisableBCT'
[Error] Unit1.pas(85): 'THEN' expected but identifier 'Checked' found
[Error] Unit1.pas(90): Undeclared identifier: 'AvrDudeID'
[Error] Unit1.pas(91): Undeclared identifier: 'btnStop'
[Error] Unit1.pas(108): Missing operator or semicolon
[Error] Unit1.pas(115): Missing operator or semicolon
[Error] Unit1.pas(124): Missing operator or semicolon
[Error] Unit1.pas(125): Missing operator or semicolon
[Error] Unit1.pas(170): Undeclared identifier: 'StartAvrDude'
[Fatal Error] Project1.dpr(5): Could not compile used unit 'Unit1.pas'
если есть скомпилированный проект поделитесь пожалуйста... |
|
#7
|
||||
|
||||
|
А говоришь, что
Цитата:
StartAvrDude - разумеется, это название метода, и его нужно объявить. mmLog - конечно, это TMemo, которое лежит на форме. WT - поток, посторонний. Его можно снести. CreateAvrDudeProcess - надстройка над CreateProcess с патчем запускаемой проги. Патч тебе не нужен. S - строка. Не видно? cbAvrDude - ComboBox, можно убрать. cbDisableBCT тоже. AvrDudeID - объявить или убрать. btnStop - К.О. Если бы нормально прочитал код и разобрался - 95% ошибок бы исчезли. Последний раз редактировалось Bargest, 26.05.2013 в 21:41. |
|
#8
|
|||
|
|||
|
Цитата:
... Извини за беспокойство.... |
|
#9
|
||||
|
||||
|
Надо не посносить, а прочитать и понять код. Небось убрал создание процесса, вместо того, чтобы заменить, убрал строки и мемо?
|