Форум по Delphi программированию

Delphi Sources



Вернуться   Форум по Delphi программированию > Все о Delphi > Разное
Ник
Пароль
Регистрация <<         Правила форума         >> FAQ Пользователи Календарь Поиск Сообщения за сегодня Все разделы прочитаны

Ответ
 
Опции темы Поиск в этой теме Опции просмотра
  #1  
Старый 12.01.2015, 20:48
Agat330 Agat330 вне форума
Прохожий
 
Регистрация: 08.04.2014
Сообщения: 26
Версия Delphi: Delphi 7
Репутация: 10
По умолчанию Глюки в командной строке

Есть вот такой код:
Код:
function TForm1.RunCmd(CommandLine: string): boolean;
type
  OEMString = type AnsiString(CP_OEMCP);

var
  I, dwAvail: byte;
  OEMStr: OEMString;
  U: UnicodeString;
  Flag: boolean;
  tRead, cWrite: THandle;
  dwRead: cardinal;
  SA: TSecurityAttributes;
  PI: TProcessInformation;
  SI: TStartupInfo;

begin
  Result:=False;

  SA.nLength:=SizeOf(SECURITY_ATTRIBUTES);
  SA.bInheritHandle:=True;
  SA.lpSecurityDescriptor:=nil;

  if not CreatePipe(tRead, cWrite, @SA, 0) then Exit;

  ZeroMemory(@SI, SizeOf(TStartupInfo));

  SI.cb:=SizeOf(TStartupInfo);
  SI.dwFlags:=STARTF_USESTDHANDLES or STARTF_USESHOWWINDOW;
  SI.wShowWindow:=SW_HIDE;
  SI.hStdOutput:=cWrite;

  if CreateProcess(nil,
                  PChar(CommandLine),
                  nil,
                  nil,
                  True,
                  0,
                  nil,
                  nil,
                  SI,
                  PI)
  then
  begin
      CloseHandle(PI.hProcess);
      CloseHandle(PI.hThread);
      CmdMemo.Clear;
      Flag:=True;

      while Flag do
      begin

         for I:=0 to 9 do
         begin
             PeekNamedPipe(tRead, nil, 0, nil, @dwAvail, nil);

             if dwAvail>0
             then
                 begin
                 Flag:=True;
                 Break;
                 end
             else Flag:=False;

             Sleep(100);
         end; //for I:=

         if dwAvail>0
         then
         begin
             SetLength(OEMStr, dwAvail);
             ReadFile(tRead, PChar(OEMStr)^, Length(OEMStr), dwRead, Nil);
             U := OEMStr;
             CmdMemo.Lines.Add(U);
             Application.ProcessMessages;
             Result:=True;
         end; // if dwAvail

      end;    // while Flag

  end;       // if CreateProcess
end;

При выполнении получается такая картинка: скрин на яндексе

То есть посередине пятой строки программа вешается. Понимаю, что где-то закрался косяк (и не один)), но не понимаю, где

p.s.: Delphi XE3

Последний раз редактировалось Agat330, 12.01.2015 в 20:56.
Ответить с цитированием
  #2  
Старый 12.01.2015, 21:27
Аватар для Freeman
Freeman Freeman вне форума
Местный
 
Регистрация: 05.10.2012
Адрес: Санкт-Петербург
Сообщения: 576
Версия Delphi: 6
Репутация: выкл
По умолчанию

Цикл какой-то странный. Разве пайп не генерирует обычных сообщений синхронизации, чтобы можно было пользоваться WaitForSingleObject?
__________________
Не стоит путать форумы с богадельнями. © Bargest
Ответить с цитированием
  #3  
Старый 12.01.2015, 21:46
Agat330 Agat330 вне форума
Прохожий
 
Регистрация: 08.04.2014
Сообщения: 26
Версия Delphi: Delphi 7
Репутация: 10
По умолчанию

Ну, в пайпах я дуб, так что код не мой. Основная часть отсюда, плюс отсюда, как побороть кодировку. Чую, скоро совсем с миру по нитке прога будет
Ответить с цитированием
  #4  
Старый 13.01.2015, 00:46
Аватар для Freeman
Freeman Freeman вне форума
Местный
 
Регистрация: 05.10.2012
Адрес: Санкт-Петербург
Сообщения: 576
Версия Delphi: 6
Репутация: выкл
По умолчанию

Ха-ха, то-то же я смотрю, что код работы с OEM-кодировкой такой знакомый. Хоть кто-то на форуме поиском пользуется, и то радость.
__________________
Не стоит путать форумы с богадельнями. © Bargest
Ответить с цитированием
  #5  
Старый 13.01.2015, 16:43
Agat330 Agat330 вне форума
Прохожий
 
Регистрация: 08.04.2014
Сообщения: 26
Версия Delphi: Delphi 7
Репутация: 10
По умолчанию

Так в чем ошибка?
Ответить с цитированием
  #6  
Старый 14.01.2015, 23:39
Agat330 Agat330 вне форума
Прохожий
 
Регистрация: 08.04.2014
Сообщения: 26
Версия Delphi: Delphi 7
Репутация: 10
По умолчанию

Блин, только обрадовался, что отозвались,.. и тишина...
Ответить с цитированием
  #7  
Старый 18.07.2015, 00:03
Agat330 Agat330 вне форума
Прохожий
 
Регистрация: 08.04.2014
Сообщения: 26
Версия Delphi: Delphi 7
Репутация: 10
По умолчанию

Снова здрасти! )) В общем, в том проекте год назад пришлось отказаться от примочек в консоли и пойти другим путем. Каким - уже не важно, это будет оффтоп. Прикол в том, что недавно мне снова пришлось писать прогу, в которой теперь уже точно нужен перехват вывода из консоли в Memo. В общем, у меня на XE-3 завелся код отсюда (ну, очень похоже на код, с которым я парился тогда)) с единственной правкой:
Var Buffer: PAnsiChar;
Ответить с цитированием
  #8  
Старый 02.08.2015, 02:33
Agat330 Agat330 вне форума
Прохожий
 
Регистрация: 08.04.2014
Сообщения: 26
Версия Delphi: Delphi 7
Репутация: 10
Вопрос Не могу понять, что снова не так

Код:
procedure RunDosInMemo(CmdLine: string; AMemo: TMemo);
const
  ReadBuffer = 2400;
var
  Security: TSecurityAttributes;
  ReadPipe, WritePipe: THandle;
  start: TStartUpInfo;
  ProcessInfo: TProcessInformation;
  Buffer: PAnsiChar;
  BytesRead: DWord;
  Apprunning: DWord;
begin
  Screen.Cursor := CrHourGlass;
  Form1.Button1.Enabled := False;
  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(CmdLine),
      @Security,
      @Security,
      true,
      NORMAL_PRIORITY_CLASS,
      nil,
      nil,
      start,
      ProcessInfo) then
    begin
      repeat
        Apprunning := WaitForSingleObject
          (ProcessInfo.hProcess, 100);
        ReadFile(ReadPipe, Buffer[0],
          ReadBuffer, BytesRead, nil);
        Buffer[BytesRead] := #0;
        OemToAnsi(Buffer, Buffer);
        AMemo.Text := AMemo.text + string(Buffer);

        Application.ProcessMessages;
      until (Apprunning <> WAIT_TIMEOUT);
    end;
    FreeMem(Buffer);
    CloseHandle(ProcessInfo.hProcess);
    CloseHandle(ProcessInfo.hThread);
    CloseHandle(ReadPipe);
    CloseHandle(WritePipe);
  end;
  Screen.Cursor := CrDefault;
  Form1.Button1.Enabled := True;
end;

Снова всем здрасти!)) Как писал выше - у меня заработал этот код вот в этом виде. То есть если на вход процедуры я даю "ping ya.ru" и memo-объект - в мемо все отлично, яндекс пингуется. Но если любую из команд adb - (adb devices, например) программа виснет, приходится убивать процесс. Заранее скажу, что exe'шник программы я после компиляции копирую в папку, где находится adb.exe. Помогите понять, что не так делаю или идеями поделитесь...

Последний раз редактировалось Agat330, 02.08.2015 в 02:35.
Ответить с цитированием
  #9  
Старый 02.08.2015, 14:51
Аватар для Bargest
Bargest Bargest вне форума
Профессионал
 
Регистрация: 19.10.2010
Адрес: Москва
Сообщения: 2,390
Версия Delphi: XE3/VS12/FASM
Репутация: 14665
По умолчанию

Посмотри под отладкой этот цикл. Может ADB ждет какого-то ввода или еще чего-нибудь. Еще ADB при старте пытается запустить свой daemon, может с этим какие-то косяки. Я с ADB код на C# делал, там все эти пайпы автоматом обрабатываются, но все равно обплевался - постоянно какие-то проблемы были с этим гугловым поделием.
А вообще, насколько я помню, ADB поддерживает работу через псевдосокеты. Можно один раз запустить его сервер, а потом слать команды на localhost.
Вот что-то типа документации (см. "II. Protocol details:"), а тут сами команды. Найти их непросто, мало кто это юзает, хотя имхо в миллион раз удобнее тупого перехвата и парсинга текста из консоли.
__________________
jmp $ ; Happy End!
The Cake Is A Lie.

Последний раз редактировалось Bargest, 02.08.2015 в 15:12.
Ответить с цитированием
  #10  
Старый 02.08.2015, 17:18
Agat330 Agat330 вне форума
Прохожий
 
Регистрация: 08.04.2014
Сообщения: 26
Версия Delphi: Delphi 7
Репутация: 10
По умолчанию

Уау!!! Круто!!! Не знал, буду пробовать, спасибо)))
А "посмотри под отладкой цикл" - я дуб в отладке (((

Последний раз редактировалось Agat330, 02.08.2015 в 17:23.
Ответить с цитированием
  #11  
Старый 02.08.2015, 20:33
Аватар для Bargest
Bargest Bargest вне форума
Профессионал
 
Регистрация: 19.10.2010
Адрес: Москва
Сообщения: 2,390
Версия Delphi: XE3/VS12/FASM
Репутация: 14665
По умолчанию

Цитата:
я дуб в отладке (((
Тогда учись, потому что без отладки время на разработку программ сложнее helloworld-ов будет увеличиваться в геометрической прогрессии по мере возрастания сложности.
__________________
jmp $ ; Happy End!
The Cake Is A Lie.

Последний раз редактировалось Bargest, 03.08.2015 в 15:05.
Ответить с цитированием
  #12  
Старый 04.08.2015, 10:54
Agat330 Agat330 вне форума
Прохожий
 
Регистрация: 08.04.2014
Сообщения: 26
Версия Delphi: Delphi 7
Репутация: 10
По умолчанию

Bargest, подскажи литературу или сайты для начинающитх отладчиков
Ответить с цитированием
  #13  
Старый 04.08.2015, 14:24
Аватар для Bargest
Bargest Bargest вне форума
Профессионал
 
Регистрация: 19.10.2010
Адрес: Москва
Сообщения: 2,390
Версия Delphi: XE3/VS12/FASM
Репутация: 14665
По умолчанию

Каких еще "начинающих отладчиков"? Просто берешь и отлаживаешь. По запросу "отладка delphi" выводятся тысячи статей. Там изучать-то нечего.
__________________
jmp $ ; Happy End!
The Cake Is A Lie.
Ответить с цитированием
Ответ


Delphi Sources

Опции темы Поиск в этой теме
Поиск в этой теме:

Расширенный поиск
Опции просмотра

Ваши права в разделе
Вы не можете создавать темы
Вы не можете отвечать на сообщения
Вы не можете прикреплять файлы
Вы не можете редактировать сообщения

BB-коды Вкл.
Смайлы Вкл.
[IMG] код Вкл.
HTML код Выкл.
Быстрый переход


Часовой пояс GMT +3, время: 05:09.


 

Сайт

Форум

FAQ

RSS лента

Прочее

 

Copyright © Форум "Delphi Sources" by BrokenByte Software, 2004-2023

ВКонтакте   Facebook   Twitter