Добро пожаловать в форум, Guest  >>   Войти | Регистрация | Поиск | Правила | В избранное | Подписаться
Все форумы / Delphi Новый топик    Ответить
Топик располагается на нескольких страницах: Ctrl  назад   1 [2]      все
 Re: После выполнения CreateProcess зависаем на WaitForSingleObject  [new]
segor
Member

Откуда:
Сообщений: 25
Повторюсь, что сей зависон возникает не со всеми консольными приложениями, но как-то связан с их выводом.

Друзья, кто может удаленно помочь - напишите, пжалста, в телегу @khudiakov_s
Моя благодарность не будет иметь границ)) Сил уже нет...
19 ноя 20, 11:24    [22235166]     Ответить | Цитировать Сообщить модератору
 Re: После выполнения CreateProcess зависаем на WaitForSingleObject  [new]
segor
Member

Откуда:
Сообщений: 25
Кроик Семён
segor,
попробуйте этот код


Извиняюсь, выше неверно указал кусок кода.
Тут зависает:
               repeat
                  BytesRead := 0;
                  ReadFile(readableEndOfPipe, Buffer[0], READ_BUFFER_SIZE, {var}BytesRead, nil);
                  Buffer[BytesRead]:= #0;
                  OemToAnsi(Buffer,Buffer);
                  AOutput.Text := AOutput.Text + String(Buffer);
               until (BytesRead < READ_BUFFER_SIZE);
19 ноя 20, 11:27    [22235176]     Ответить | Цитировать Сообщить модератору
 Re: После выполнения CreateProcess зависаем на WaitForSingleObject  [new]
segor
Member

Откуда:
Сообщений: 25
wadman
segor
пропущено...


Попробовал.
Зависает тут:
      repeat
        ReadFile(ReadPipe, Buffer, ReadBuffer, BytesRead, nil);
        Buffer[BytesRead] := #0;
        result := result + Buffer;
 
 
      until (BytesRead < ReadBuffer);

Жесть... А если прочитается ровно столько сколько в буфере максимум? Что будет с последним байтом?


Там будет последний прочитанный байт. Разве нет?
19 ноя 20, 11:29    [22235179]     Ответить | Цитировать Сообщить модератору
 Re: После выполнения CreateProcess зависаем на WaitForSingleObject  [new]
wadman
Member

Откуда: Санкт-Петербург
Сообщений: 26836
segor
wadman
пропущено...

Жесть... А если прочитается ровно столько сколько в буфере максимум? Что будет с последним байтом?


Там будет последний прочитанный байт. Разве нет?


Кроик Семён
Buffer := AllocMem(READ_BUFFER_SIZE+1);

Отставить панику. Это моя невнимательность. Всё нормально. :)
19 ноя 20, 11:31    [22235181]     Ответить | Цитировать Сообщить модератору
 Re: После выполнения CreateProcess зависаем на WaitForSingleObject  [new]
wadman
Member

Откуда: Санкт-Петербург
Сообщений: 26836
segor
Извиняюсь, выше неверно указал кусок кода.
Тут зависает:

Там чуть выше есть комментарий:
Кроик Семён
//WARNING: if the console app never writes anything to the StdOutput, then ReadFile will block and never return
19 ноя 20, 11:33    [22235183]     Ответить | Цитировать Сообщить модератору
 Re: После выполнения CreateProcess зависаем на WaitForSingleObject  [new]
segor
Member

Откуда:
Сообщений: 25
wadman
segor
Извиняюсь, выше неверно указал кусок кода.
Тут зависает:

Там чуть выше есть комментарий:
Кроик Семён
//WARNING: if the console app never writes anything to the StdOutput, then ReadFile will block and never return


Но подвисает как раз когда есть вывод(
19 ноя 20, 11:39    [22235188]     Ответить | Цитировать Сообщить модератору
 Re: После выполнения CreateProcess зависаем на WaitForSingleObject  [new]
Kazantsev Alexey
Member

Откуда:
Сообщений: 4724
segor
Друзья, кто может удаленно помочь - напишите, пжалста, в телегу @khudiakov_s
Моя благодарность не будет иметь границ)) Сил уже нет...


Ты готовое решение пробовал? https://www.sql.ru/forum/actualutils.aspx?action=gotomsg&tid=1330938&msg=22233231
19 ноя 20, 11:45    [22235196]     Ответить | Цитировать Сообщить модератору
 Re: После выполнения CreateProcess зависаем на WaitForSingleObject  [new]
Zelius
Member

Откуда: Россия, Москва
Сообщений: 1475
segor,

посмотри здесь, не зависает, передает данные на вход, вычитывает все что передано обратно...

Перенаправление вывода в файл
19 ноя 20, 11:45    [22235197]     Ответить | Цитировать Сообщить модератору
 Re: После выполнения CreateProcess зависаем на WaitForSingleObject  [new]
alekcvp
Member

Откуда:
Сообщений: 2494
У меня как-то так сделано, ничего не подвисает:

  procedure ProcessFlow(hProcess, hReadPipe: THandle);
  const
    BUFFER_SIZE = 1024;
  var
    BytesAvail: Cardinal;
    BytesRead: Cardinal;
    Buffer: array [0..BUFFER_SIZE - 1] of AnsiChar;
    dwWait: Cardinal;
  begin
    repeat
      dwWait := WaitForSingleObject(hProcess, 100);
      WinAPICheck(PeekNamedPipe(hReadPipe, nil, 0, nil, @BytesAvail, nil), 'PeekNamedPipe');
      while BytesAvail > 0 do
      begin
        WinAPICheck(
          ReadFile(hReadPipe, @Buffer[0], Min(BytesAvail, BUFFER_SIZE), @BytesRead, nil), 'ReadFile');
        if BytesRead = 0 then Break; // что-то пошло не так
        Dec(BytesAvail, BytesRead);
//        OemToCharBuffA(@Buffer[0], @Buffer[0], BytesRead);
        Обрабатываем Buffer
      end;
    until dwWait <> WAIT_TIMEOUT;
  end;

P.S: Повырезал всё лишнее.

Сообщение было отредактировано: 19 ноя 20, 11:46
19 ноя 20, 11:50    [22235202]     Ответить | Цитировать Сообщить модератору
 Re: После выполнения CreateProcess зависаем на WaitForSingleObject  [new]
YuRock
Member

Откуда: Донецк
Сообщений: 4339
wadman
Всё нормально
Ну я б не сказал.
Если ReadFile начнет возвращать False, или размер прочитанного окажется меньше ожидаемого - будет вечный цикл.
Каша-алгоритм это, а не всё нормально. Надежда только на везение.

Сообщение было отредактировано: 19 ноя 20, 11:55
19 ноя 20, 12:00    [22235207]     Ответить | Цитировать Сообщить модератору
 Re: После выполнения CreateProcess зависаем на WaitForSingleObject  [new]
segor
Member

Откуда:
Сообщений: 25
Kazantsev Alexey
segor
Друзья, кто может удаленно помочь - напишите, пжалста, в телегу @khudiakov_s
Моя благодарность не будет иметь границ)) Сил уже нет...


Ты готовое решение пробовал? https://www.sql.ru/forum/actualutils.aspx?action=gotomsg&tid=1330938&msg=22233231


Я его не осилил( Не хватает знаниев. Не компилируется.
19 ноя 20, 12:07    [22235211]     Ответить | Цитировать Сообщить модератору
 Re: После выполнения CreateProcess зависаем на WaitForSingleObject  [new]
Kazantsev Alexey
Member

Откуда:
Сообщений: 4724
segor,

Какая у тебя версия Delphi?
19 ноя 20, 12:49    [22235247]     Ответить | Цитировать Сообщить модератору
 Re: После выполнения CreateProcess зависаем на WaitForSingleObject  [new]
segor
Member

Откуда:
Сообщений: 25
Kazantsev Alexey
segor,

Какая у тебя версия Delphi?


10.3
19 ноя 20, 13:25    [22235285]     Ответить | Цитировать Сообщить модератору
 Re: После выполнения CreateProcess зависаем на WaitForSingleObject  [new]
Dimitry Sibiryakov
Member

Откуда:
Сообщений: 51775

segor
Я его не осилил( Не хватает знаниев. Не компилируется.

Ну так прокачивай знания пока не осилишь.

Posted via ActualForum NNTP Server 1.5

19 ноя 20, 13:38    [22235301]     Ответить | Цитировать Сообщить модератору
 Re: После выполнения CreateProcess зависаем на WaitForSingleObject  [new]
Kazantsev Alexey
Member

Откуда:
Сообщений: 4724
segor,

+ Упрощённый ExecuteProcess
program Project1;

{$APPTYPE CONSOLE}

uses
  SysUtils,
  Windows;

//
Function ExecuteProcess(Const AExecutable, ACommandLine, ACurrentDir : String; ACodePage : Word = CP_OEMCP) : String;
Const

 CP_UTF16_LE = 1200;

Var

 RPipe     : THandle;
 WPipe     : THandle;
 SA        : TSecurityAttributes;
 SI        : TStartupInfo;
 PA        : TProcessInformation;
 Buffer    : Array [0 .. 128 - 1] Of Byte;
 Count     : Cardinal;
 AccBuffer : RawByteString;

Begin

 Result := '';

 //
 ZeroMemory(@SA, SizeOf(SA));

 SA.nLength              := SizeOf(SA);
 SA.lpSecurityDescriptor := NIL;
 SA.bInheritHandle       := True;
 //

 If Not CreatePipe(RPipe, WPipe, @SA, 0) Then
  RaiseLastOSError;

 Try

  //
  ZeroMemory(@SI, SizeOf(SI));

  SI.cb          := SizeOf(SI);
  SI.hStdOutput  := WPipe;
  SI.hStdError   := WPipe;
  SI.dwFlags     := STARTF_USESTDHANDLES Or STARTF_USESHOWWINDOW;
  SI.wShowWindow := SW_HIDE;
  //

  //
  ZeroMemory(@PA, SizeOf(PA));
  //

  If CreateProcess(PChar(AExecutable), PChar(ACommandLine), NIL, NIL, True, 0, NIL, PChar(Pointer(ACurrentDir)), SI, PA) Then
   Try

    If WPipe <> INVALID_HANDLE_VALUE Then
     Begin

      CloseHandle(WPipe);

      WPipe := INVALID_HANDLE_VALUE;

     End;

    While ReadFile(RPipe, Buffer, SizeOf(Buffer), Count, NIL) And (Count > 0) Do
     Begin

      SetLength(AccBuffer, Length(AccBuffer) + Integer(Count));
      Move(Buffer, AccBuffer[Length(AccBuffer) - Integer(Count) + 1], Count);

     End;

    If ACodePage = CP_UTF16_LE Then
     Begin

      SetLength(Result, Length(AccBuffer) Div SizeOf(WideChar));
      Move(Pointer(AccBuffer)^, Pointer(Result)^, Length(Result) * SizeOf(WideChar));

     End
    Else
     Begin

      SetCodePage(AccBuffer, ACodePage, False);

      Result := String(AccBuffer);

     End;

   Finally

    WaitForSingleObject(PA.hProcess, INFINITE);

    CloseHandle(PA.hThread);
    CloseHandle(PA.hProcess);

   End
  Else
   RaiseLastOSError;

 Finally

  If RPipe <> INVALID_HANDLE_VALUE Then
   CloseHandle(RPipe);

  If WPipe <> INVALID_HANDLE_VALUE Then
   CloseHandle(WPipe);

 End;

End;
//

var
 s : string;
begin

 WriteLn(ExecuteProcess('C:\Program Files (x86)\Embarcadero\Studio\20.0\bin\dcc32.exe', '', ''));

 s := ExecuteProcess('c:\windows\system32\cmd.exe', '/U /C dir', 'c:\', 1200);
 MessageBox(0, PChar(s), 'cmd', MB_ICONINFORMATION or MB_OK);

end.
19 ноя 20, 13:39    [22235303]     Ответить | Цитировать Сообщить модератору
 Re: После выполнения CreateProcess зависаем на WaitForSingleObject  [new]
Fr0sT-Brutal
Member

Откуда:
Сообщений: 459
Да возьмите у джедаев и все
19 ноя 20, 18:09    [22235599]     Ответить | Цитировать Сообщить модератору
 Re: После выполнения CreateProcess зависаем на WaitForSingleObject  [new]
makhaon
Member

Откуда: A galaxy far far away
Сообщений: 3731
возьмите готовое и многократно опробованное решение в жедаях. так вам нравится ковыряться в велосипедах, которые уже лет 20 как отлично решены
19 ноя 20, 18:58    [22235643]     Ответить | Цитировать Сообщить модератору
 Re: После выполнения CreateProcess зависаем на WaitForSingleObject  [new]
segor
Member

Откуда:
Сообщений: 25
Спасибо. Покурим с джедаями)
19 ноя 20, 19:34    [22235659]     Ответить | Цитировать Сообщить модератору
 Re: После выполнения CreateProcess зависаем на WaitForSingleObject  [new]
segor
Member

Откуда:
Сообщений: 25
Kazantsev Alexey
segor,

+ Упрощённый ExecuteProcess
program Project1;

{$APPTYPE CONSOLE}

uses
  SysUtils,
  Windows;

//
Function ExecuteProcess(Const AExecutable, ACommandLine, ACurrentDir : String; ACodePage : Word = CP_OEMCP) : String;
Const

 CP_UTF16_LE = 1200;

Var

 RPipe     : THandle;
 WPipe     : THandle;
 SA        : TSecurityAttributes;
 SI        : TStartupInfo;
 PA        : TProcessInformation;
 Buffer    : Array [0 .. 128 - 1] Of Byte;
 Count     : Cardinal;
 AccBuffer : RawByteString;

Begin

 Result := '';

 //
 ZeroMemory(@SA, SizeOf(SA));

 SA.nLength              := SizeOf(SA);
 SA.lpSecurityDescriptor := NIL;
 SA.bInheritHandle       := True;
 //

 If Not CreatePipe(RPipe, WPipe, @SA, 0) Then
  RaiseLastOSError;

 Try

  //
  ZeroMemory(@SI, SizeOf(SI));

  SI.cb          := SizeOf(SI);
  SI.hStdOutput  := WPipe;
  SI.hStdError   := WPipe;
  SI.dwFlags     := STARTF_USESTDHANDLES Or STARTF_USESHOWWINDOW;
  SI.wShowWindow := SW_HIDE;
  //

  //
  ZeroMemory(@PA, SizeOf(PA));
  //

  If CreateProcess(PChar(AExecutable), PChar(ACommandLine), NIL, NIL, True, 0, NIL, PChar(Pointer(ACurrentDir)), SI, PA) Then
   Try

    If WPipe <> INVALID_HANDLE_VALUE Then
     Begin

      CloseHandle(WPipe);

      WPipe := INVALID_HANDLE_VALUE;

     End;

    While ReadFile(RPipe, Buffer, SizeOf(Buffer), Count, NIL) And (Count > 0) Do
     Begin

      SetLength(AccBuffer, Length(AccBuffer) + Integer(Count));
      Move(Buffer, AccBuffer[Length(AccBuffer) - Integer(Count) + 1], Count);

     End;

    If ACodePage = CP_UTF16_LE Then
     Begin

      SetLength(Result, Length(AccBuffer) Div SizeOf(WideChar));
      Move(Pointer(AccBuffer)^, Pointer(Result)^, Length(Result) * SizeOf(WideChar));

     End
    Else
     Begin

      SetCodePage(AccBuffer, ACodePage, False);

      Result := String(AccBuffer);

     End;

   Finally

    WaitForSingleObject(PA.hProcess, INFINITE);

    CloseHandle(PA.hThread);
    CloseHandle(PA.hProcess);

   End
  Else
   RaiseLastOSError;

 Finally

  If RPipe <> INVALID_HANDLE_VALUE Then
   CloseHandle(RPipe);

  If WPipe <> INVALID_HANDLE_VALUE Then
   CloseHandle(WPipe);

 End;

End;
//

var
 s : string;
begin

 WriteLn(ExecuteProcess('C:\Program Files (x86)\Embarcadero\Studio\20.0\bin\dcc32.exe', '', ''));

 s := ExecuteProcess('c:\windows\system32\cmd.exe', '/U /C dir', 'c:\', 1200);
 MessageBox(0, PChar(s), 'cmd', MB_ICONINFORMATION or MB_OK);

end.


Спасибо )
19 ноя 20, 19:36    [22235660]     Ответить | Цитировать Сообщить модератору
 Re: После выполнения CreateProcess зависаем на WaitForSingleObject  [new]
makhaon
Member

Откуда: A galaxy far far away
Сообщений: 3731
segor
Спасибо. Покурим с джедаями)

Что бы долго не искать:
https://github.com/project-jedi/jcl/blob/9d89903a2ee38fa72be47df433c46c7747ba4025/jcl/source/common/JclSysUtils.pas#L501

Сообщение было отредактировано: 20 ноя 20, 10:46
20 ноя 20, 10:48    [22235899]     Ответить | Цитировать Сообщить модератору
Топик располагается на нескольких страницах: Ctrl  назад   1 [2]      все
Все форумы / Delphi Ответить