Показать сообщение отдельно
  #3  
Старый 26.05.2013, 20:42
Аватар для Bargest
Bargest Bargest вне форума
Профессионал
 
Регистрация: 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.
Ответить с цитированием