
26.05.2013, 20:42
|
 |
Профессионал
|
|
Регистрация: 19.10.2010
Адрес: Москва
Сообщения: 2,390
Версия Delphi: XE3/VS12/FASM
Репутация: 14665
|
|
А мне почему-то копипаста помогла:
Код:
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;
Честно спиз сперто из гугла.
__________________
jmp $ ; Happy End!
The Cake Is A Lie.
|