powered by simpleCommunicator - 2.0.61     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / Delphi [игнор отключен] [закрыт для гостей] / После выполнения CreateProcess зависаем на WaitForSingleObject
45 сообщений из 45, показаны все 2 страниц
После выполнения CreateProcess зависаем на WaitForSingleObject
    #40019001
segor
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Всем привет!
Подскажите, пожалуйста:

Необходимо выполнять консольное приложение и получить его вывод.

Нашел такой код:

Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
function Run_Dos(CmdLine: string) : string;
const
  ReadBuffer = 255;
var
  Security: TSecurityAttributes;
  ReadPipe, WritePipe: THandle;
  start: TStartUpInfo;
  ProcessInfo: TProcessInformation;
  Buffer: array [0 .. 255] of AnsiChar;
  BytesRead: DWord;
  Apprunning: DWord;
begin
 
  with Security do
  begin
    nlength := SizeOf(TSecurityAttributes);
    binherithandle := true;
    lpsecuritydescriptor := nil;
  end;
  if Createpipe(ReadPipe, WritePipe,
    @Security, 0) then
  begin
    result := '';
 
    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
 
//     Apprunning := WaitForSingleObject(ProcessInfo.hProcess, 10000);
     Apprunning := WaitForSingleObject(ProcessInfo.hProcess, infinite);
 
 
    //перед чтением из пайпа закрыть один конец
     CloseHandle(WritePipe);
 
      repeat
        ReadFile(ReadPipe, Buffer, ReadBuffer, BytesRead, nil);
        Buffer[BytesRead] := #0;
        result := result + Buffer;
 
 
      until (BytesRead < ReadBuffer);
    end;
 
    CloseHandle(ProcessInfo.hProcess);
    CloseHandle(ProcessInfo.hThread);
    CloseHandle(ReadPipe);
  end;
 
end;



Но, к сожалению, он не со всеми приложениями работает корректно. Выполнение некоторых консольных приложений привод к зависанию вот в этом месте:

Код: pascal
1.
     Apprunning := WaitForSingleObject(ProcessInfo.hProcess, infinite);



(в диспетчере задач видим незавершенный процесс запущенного консольного приложения)

Если это же консольное приложение выполнять из командной строки - то все выполняется корректно (выводит результаты в консоль и завершается).

Что в коде не так?
...
Рейтинг: 0 / 0
После выполнения CreateProcess зависаем на WaitForSingleObject
    #40019008
Kazantsev Alexey
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
segor
Выполнение некоторых консольных приложений привод к зависанию вот в этом месте

Перенеси эту строчку после цикла чтения из пайпа.
...
Рейтинг: 0 / 0
После выполнения CreateProcess зависаем на WaitForSingleObject
    #40019016
Dimitry Sibiryakov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
segorЧто в коде не так?

В коде много чего неправильно. Изучай оригинал:
https://docs.microsoft.com/en-us/windows/win32/ProcThread/creating-a-child-process-with-redirected-input-and-output
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
После выполнения CreateProcess зависаем на WaitForSingleObject
    #40019018
segor
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Kazantsev Alexey
segor
Выполнение некоторых консольных приложений привод к зависанию вот в этом месте

Перенеси эту строчку после цикла чтения из пайпа.


Перенес. Все равно на ней виснет.
...
Рейтинг: 0 / 0
После выполнения CreateProcess зависаем на WaitForSingleObject
    #40019027
Фотография _Vasilisk_
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Kazantsev Alexey
Перенеси эту строчку после цикла чтения из пайпа.
Зачем? Сейчас все логично: ждем пока процесс не завершится, а потом выгребаем все из пайпа. А так, если дочерний процесс задумается перед выводом, то мы проскочим цикл и будем в тупую ждать завершения
...
Рейтинг: 0 / 0
После выполнения CreateProcess зависаем на WaitForSingleObject
    #40019036
Фотография _Vasilisk_
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
segor
Если это же консольное приложение выполнять из командной строки - то все выполняется корректно (выводит результаты в консоль и завершается).
Значит в чем-то отличие. Например в параметрах командной строки.

Сделайте
Код: pascal
1.
start.wShowWindow := SW_SHOW;

и посмотрите, что ждет приложение

Далее, поверьте, вот это
segor
Код: pascal
1.
start.hStdInput := ReadPipe;

вам не нужно
А вот эти две строки
segor
Код: pascal
1.
2.
3.
4.
//     Apprunning := WaitForSingleObject(ProcessInfo.hProcess, 10000);
     Apprunning := WaitForSingleObject(ProcessInfo.hProcess, infinite);
    //перед чтением из пайпа закрыть один конец
     CloseHandle(WritePipe);

логично будет поменять местами
...
Рейтинг: 0 / 0
После выполнения CreateProcess зависаем на WaitForSingleObject
    #40019046
Dimitry Sibiryakov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
_Vasilisk_Сейчас все логично: ждем пока процесс не завершится, а потом выгребаем все из пайпа.

Ага, но перед этим сделали с вызываемым процессом грязный трюк, описанный в одном
бородатом анекдоте фразой "а теперь циркулируй".
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
После выполнения CreateProcess зависаем на WaitForSingleObject
    #40019048
Kazantsev Alexey
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
segor
Перенес. Все равно на ней виснет.

У тебя ещё условие цикла некорректное. Чтение может вернуть меньше, чем ты просишь, но это не повод прерывать цикл.

_Vasilisk_
Сейчас все логично: ждем пока процесс не завершится, а потом выгребаем все из пайпа.

А буфер пайпа у тебя бесконечный?
...
Рейтинг: 0 / 0
После выполнения CreateProcess зависаем на WaitForSingleObject
    #40019053
segor
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
_Vasilisk_
segor
Если это же консольное приложение выполнять из командной строки - то все выполняется корректно (выводит результаты в консоль и завершается).
Значит в чем-то отличие. Например в параметрах командной строки.

Сделайте
Код: pascal
1.
start.wShowWindow := SW_SHOW;

и посмотрите, что ждет приложение

Далее, поверьте, вот это
segor
Код: pascal
1.
start.hStdInput := ReadPipe;

вам не нужно
А вот эти две строки
segor
Код: pascal
1.
2.
3.
4.
//     Apprunning := WaitForSingleObject(ProcessInfo.hProcess, 10000);
     Apprunning := WaitForSingleObject(ProcessInfo.hProcess, infinite);
    //перед чтением из пайпа закрыть один конец
     CloseHandle(WritePipe);

логично будет поменять местами


Сделал.
Появляется консольное окно. В нем мигает курсор. Вывода нет.
Тут все так же виснем WaitForSingleObject
...
Рейтинг: 0 / 0
После выполнения CreateProcess зависаем на WaitForSingleObject
    #40019055
Kazantsev Alexey
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ExecuteProcess
Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
71.
72.
73.
74.
75.
76.
77.
78.
79.
80.
81.
82.
83.
84.
85.
86.
87.
88.
89.
90.
91.
92.
93.
94.
95.
96.
//
Function ExecuteProcess(Const AExecutable, ACommandLine, ACurrentDir : String; AOnOutputDataProc : TOnOutputDataProc; ATimeoutInterval : DWORD; ATimeoutExitCode : DWORD) : LongWord;
Var

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

Begin

 Result := 0;

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

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

 If Not Assigned(AOnOutputDataProc) Then
  Begin

   RPipe := INVALID_HANDLE_VALUE;
   WPipe := INVALID_HANDLE_VALUE;

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

 Try

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

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

  //
  ZeroMem(@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;

    If ATimeoutInterval <> INFINITE Then
     TWatchdogThread.Create(PA.hProcess, ATimeoutInterval, ATimeoutExitCode);

    If Assigned(AOnOutputDataProc) Then
     While ReadFile(RPipe, Buffer, SizeOf(Buffer), Count, NIL) And (Count > 0) Do
      AOnOutputDataProc(Buffer, Count);

   Finally

    WaitForSingleObject(PA.hProcess, INFINITE);

    If Not GetExitCodeProcess(PA.hProcess, Result) Then
     RaiseLastOSError;

    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;
//

...
Рейтинг: 0 / 0
После выполнения CreateProcess зависаем на WaitForSingleObject
    #40019056
bk0010
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
segor
Если это же консольное приложение выполнять из командной строки - то все выполняется корректно (выводит результаты в консоль и завершается).
Точно завершается? Не пишет "Press any key"?
...
Рейтинг: 0 / 0
После выполнения CreateProcess зависаем на WaitForSingleObject
    #40019057
segor
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Dimitry Sibiryakov

segorЧто в коде не так?

В коде много чего неправильно. Изучай оригинал:
https://docs.microsoft.com/en-us/windows/win32/ProcThread/creating-a-child-process-with-redirected-input-and-output


Ок, спасибо, будем изучать.
...
Рейтинг: 0 / 0
После выполнения CreateProcess зависаем на WaitForSingleObject
    #40019058
segor
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
bk0010
segor
Если это же консольное приложение выполнять из командной строки - то все выполняется корректно (выводит результаты в консоль и завершается).
Точно завершается? Не пишет "Press any key"?


Да точно. В диспетчере задач появляется после запуска и пропадает после завершения работы.
...
Рейтинг: 0 / 0
После выполнения CreateProcess зависаем на WaitForSingleObject
    #40019079
Фотография _Vasilisk_
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
segor
Появляется консольное окно. В нем мигает курсор. Вывода нет.
Логично, вы же весь вывод затягиваете к себе в программу.

Делайте так
segor
Код: pascal
1.
start.dwFlags := STARTF_USESHOWWINDOW;

и смотрите, чего не хватает процессу. А потом вернете флаг обратно
...
Рейтинг: 0 / 0
После выполнения CreateProcess зависаем на WaitForSingleObject
    #40019084
Dimitry Sibiryakov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
_Vasilisk_Логично, вы же весь вывод затягиваете к себе в программу.

Нет. Присмотрись повнимательнее куда он засунул второй конец трубы.
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
После выполнения CreateProcess зависаем на WaitForSingleObject
    #40019092
Фотография _Vasilisk_
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dimitry Sibiryakov
Присмотрись повнимательнее куда он засунул второй конец трубы.
Это я уже говорил
_Vasilisk_
Далее, поверьте, вот это
segor
Код: pascal
1.
start.hStdInput := ReadPipe;

вам не нужно
Товарищ обещал исправить.

Ну и если программа не ожидает ввода, то это ни на что влиять не должно. А если ожидает, то код должен быть совершенно другим
...
Рейтинг: 0 / 0
После выполнения CreateProcess зависаем на WaitForSingleObject
    #40019093
segor
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
_Vasilisk_
segor
Появляется консольное окно. В нем мигает курсор. Вывода нет.
Логично, вы же весь вывод затягиваете к себе в программу.

Делайте так
segor
Код: pascal
1.
start.dwFlags := STARTF_USESHOWWINDOW;

и смотрите, чего не хватает процессу. А потом вернете флаг обратно


Сделал.
Теперь вижу в консольном окне вывод приложения так, как было бы если запускал его из командой строки.


function Run_Dosfunction Run_Dos(CmdLine: string) : string;
const
ReadBuffer = 255;
var
Security: TSecurityAttributes;
ReadPipe, WritePipe: THandle;
start: TStartUpInfo;
ProcessInfo: TProcessInformation;
Buffer: array [0 .. 255] of Char;
BytesRead: DWord;
Apprunning: DWord;
begin

with Security do
begin
nlength := SizeOf(TSecurityAttributes);
binherithandle := true;
lpsecuritydescriptor := nil;
end;
if Createpipe(ReadPipe, WritePipe,
@Security, 0) then
begin
result := '';

FillChar(Start, Sizeof(Start), #0);
start.cb := SizeOf(start);
start.hStdOutput := WritePipe;
// start.hStdInput := ReadPipe;

// start.dwFlags := STARTF_USESTDHANDLES + STARTF_USESHOWWINDOW;
start.dwFlags := STARTF_USESHOWWINDOW;

// start.wShowWindow := SW_HIDE;
start.wShowWindow := SW_SHOW;


if CreateProcess(nil,
PChar(CmdLine),
@Security,
@Security,
true,
NORMAL_PRIORITY_CLASS,
nil,
nil,
start,
ProcessInfo) then
begin


//перед чтением из пайпа закрыть один конец
CloseHandle(WritePipe);

Apprunning := WaitForSingleObject(ProcessInfo.hProcess, infinite);




repeat
ReadFile(ReadPipe, Buffer, ReadBuffer, BytesRead, nil);
Buffer[BytesRead] := #0;
result := result + Buffer;


until (BytesRead < ReadBuffer);
end;


CloseHandle(ProcessInfo.hProcess);
CloseHandle(ProcessInfo.hThread);
CloseHandle(ReadPipe);



end;

end;

...
Рейтинг: 0 / 0
После выполнения CreateProcess зависаем на WaitForSingleObject
    #40019094
Фотография _Vasilisk_
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
segor
Теперь вижу в консольном окне вывод приложения так, как было бы если запускал его из командой строки.
И приложение само завершается? Или ждет ввода от пользователя и только потом завершается?
...
Рейтинг: 0 / 0
После выполнения CreateProcess зависаем на WaitForSingleObject
    #40019095
segor
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
_Vasilisk_
segor
Теперь вижу в консольном окне вывод приложения так, как было бы если запускал его из командой строки.
И приложение само завершается? Или ждет ввода от пользователя и только потом завершается?


Само.
...
Рейтинг: 0 / 0
После выполнения CreateProcess зависаем на WaitForSingleObject
    #40019494
Фотография _Vasilisk_
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
segor
Само.
Я правильно понял, что если поставить
Код: pascal
1.
start.dwFlags := STARTF_USESHOWWINDOW;

то запущенное приложение завершается само и ваша программа не зависает? При этом в запущенном приложении вы не нажимаете никаких клавиш?
...
Рейтинг: 0 / 0
После выполнения CreateProcess зависаем на WaitForSingleObject
    #40019836
segor
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
_Vasilisk_
segor
Само.
Я правильно понял, что если поставить
Код: pascal
1.
start.dwFlags := STARTF_USESHOWWINDOW;

то запущенное приложение завершается само и ваша программа не зависает? При этом в запущенном приложении вы не нажимаете никаких клавиш?


Да, так и есть.
...
Рейтинг: 0 / 0
После выполнения CreateProcess зависаем на WaitForSingleObject
    #40019848
Фотография Кроик Семён
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
segor,

попробуйте этот код

Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
71.
72.
73.
74.
75.
76.
77.
78.
79.
80.
81.
82.
83.
84.
85.
86.
//Based on RunDosInMemo() from
//   https://stackoverflow.com/questions/9119999

procedure ExecAppAndGetOutput(const ACmdStr: string; AOutput: TStrings;
  AAsync: boolean = false);
const
   READ_BUFFER_SIZE = 2400;
var
   sCmdStr  : string;
   Security: TSecurityAttributes;
   readableEndOfPipe, writeableEndOfPipe: THandle;
   start: TStartUpInfo;
   ProcessInfo: TProcessInformation;
   Buffer: PAnsiChar;
   BytesRead: DWORD;
   AppRunning: DWORD;
begin
   sCmdStr := ACmdStr;

   Security.nLength := SizeOf(TSecurityAttributes);
   Security.bInheritHandle := True;
   Security.lpSecurityDescriptor := nil;

   if CreatePipe({var}readableEndOfPipe, {var}writeableEndOfPipe, @Security, 0) then
   begin
      Buffer := AllocMem(READ_BUFFER_SIZE+1);
      try
         FillChar(Start, Sizeof(Start), #0);
         start.cb := SizeOf(start);

         // Set up members of the STARTUPINFO structure.
         // This structure specifies the STDIN and STDOUT handles for redirection.
         // - Redirect the output and error to the writeable end of our pipe.
         // - We must still supply a valid StdInput handle (because we used STARTF_USESTDHANDLES to swear that all three handles will be valid)
         start.dwFlags := start.dwFlags or STARTF_USESTDHANDLES;
         start.hStdInput := GetStdHandle(STD_INPUT_HANDLE); //we're not redirecting stdInput; but we still have to give it a valid handle
         start.hStdOutput := writeableEndOfPipe; //we give the writeable end of the pipe to the child process; we read from the readable end
         start.hStdError := writeableEndOfPipe;

         //We can also choose to say that the wShowWindow member contains a value.
         //In our case we want to force the console window to be hidden.
         start.dwFlags := start.dwFlags + STARTF_USESHOWWINDOW;
         start.wShowWindow := SW_HIDE;

         // Don't forget to set up members of the PROCESS_INFORMATION structure.
         //--- ProcessInfo := Default(TProcessInformation);
         FillChar(ProcessInfo, SizeOf(ProcessInfo), 0);


         //WARNING: The unicode version of CreateProcess (CreateProcessW) can modify the command-line "DosApp" string.
         //Therefore "DosApp" cannot be a pointer to read-only memory, or an ACCESS_VIOLATION will occur.
         //We can ensure it's not read-only with the RTL function: UniqueString
         UniqueString({var}sCmdStr);

         try
            if CreateProcess(nil, PChar(sCmdStr), nil, nil, True, NORMAL_PRIORITY_CLASS, nil, nil, start, {var}ProcessInfo) then
            begin
               //Wait for the application to terminate, as it writes it's output to the pipe.
               //WARNING: If the console app outputs more than 2400 bytes (ReadBuffer),
               //it will block on writing to the pipe and *never* close.
               repeat
                  Apprunning := WaitForSingleObject(ProcessInfo.hProcess, 100);
                  if AAsync then Application.ProcessMessages();
               until (Apprunning <> WAIT_TIMEOUT);

               //Read the contents of the pipe out of the readable end
               //WARNING: if the console app never writes anything to the StdOutput, then ReadFile will block and never return
               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);
            end;
         finally
            CloseHandle(ProcessInfo.hProcess);
            CloseHandle(ProcessInfo.hThread);
            CloseHandle(readableEndOfPipe);
            CloseHandle(writeableEndOfPipe);
         end;
      finally
         FreeMem(Buffer);
      end;
   end; //if CreatePipe
end;
...
Рейтинг: 0 / 0
После выполнения CreateProcess зависаем на WaitForSingleObject
    #40019900
Фотография _Vasilisk_
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Код: pascal
1.
2.
3.
4.
5.
    start.hStdOutput := WritePipe;
    start.hStdInput := INVALID_HANDLE_VALUE;
 
    start.dwFlags := STARTF_USESTDHANDLES + STARTF_USESHOWWINDOW;
 
...
Рейтинг: 0 / 0
После выполнения CreateProcess зависаем на WaitForSingleObject
    #40020252
segor
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Кроик Семён
segor,

попробуйте этот код



Попробовал.
Зависает тут:
Код: pascal
1.
2.
3.
4.
5.
6.
7.
      repeat
        ReadFile(ReadPipe, Buffer, ReadBuffer, BytesRead, nil);
        Buffer[BytesRead] := #0;
        result := result + Buffer;
 
 
      until (BytesRead < ReadBuffer);
...
Рейтинг: 0 / 0
После выполнения CreateProcess зависаем на WaitForSingleObject
    #40020266
Фотография wadman
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
segor
Кроик Семён
segor,

попробуйте этот код



Попробовал.
Зависает тут:
Код: pascal
1.
2.
3.
4.
5.
6.
7.
      repeat
        ReadFile(ReadPipe, Buffer, ReadBuffer, BytesRead, nil);
        Buffer[BytesRead] := #0;
        result := result + Buffer;
 
 
      until (BytesRead < ReadBuffer);


Жесть... А если прочитается ровно столько сколько в буфере максимум? Что будет с последним байтом?
...
Рейтинг: 0 / 0
После выполнения CreateProcess зависаем на WaitForSingleObject
    #40020279
segor
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Повторюсь, что сей зависон возникает не со всеми консольными приложениями, но как-то связан с их выводом.

Друзья, кто может удаленно помочь - напишите, пжалста, в телегу @khudiakov_s
Моя благодарность не будет иметь границ)) Сил уже нет...
...
Рейтинг: 0 / 0
После выполнения CreateProcess зависаем на WaitForSingleObject
    #40020287
segor
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Кроик Семён
segor,
попробуйте этот код


Извиняюсь, выше неверно указал кусок кода.
Тут зависает:
Код: pascal
1.
2.
3.
4.
5.
6.
7.
               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);
...
Рейтинг: 0 / 0
После выполнения CreateProcess зависаем на WaitForSingleObject
    #40020290
segor
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
wadman
segor
пропущено...


Попробовал.
Зависает тут:
Код: pascal
1.
2.
3.
4.
5.
6.
7.
      repeat
        ReadFile(ReadPipe, Buffer, ReadBuffer, BytesRead, nil);
        Buffer[BytesRead] := #0;
        result := result + Buffer;
 
 
      until (BytesRead < ReadBuffer);


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


Там будет последний прочитанный байт. Разве нет?
...
Рейтинг: 0 / 0
После выполнения CreateProcess зависаем на WaitForSingleObject
    #40020291
Фотография wadman
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
segor
wadman
пропущено...

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


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


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


Отставить панику. Это моя невнимательность. Всё нормально. :)
...
Рейтинг: 0 / 0
После выполнения CreateProcess зависаем на WaitForSingleObject
    #40020292
Фотография wadman
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
segor
Извиняюсь, выше неверно указал кусок кода.
Тут зависает:

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

...
Рейтинг: 0 / 0
После выполнения CreateProcess зависаем на WaitForSingleObject
    #40020295
segor
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
wadman
segor
Извиняюсь, выше неверно указал кусок кода.
Тут зависает:

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



Но подвисает как раз когда есть вывод(
...
Рейтинг: 0 / 0
После выполнения CreateProcess зависаем на WaitForSingleObject
    #40020299
Kazantsev Alexey
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
segor
Друзья, кто может удаленно помочь - напишите, пжалста, в телегу @khudiakov_s
Моя благодарность не будет иметь границ)) Сил уже нет...


Ты готовое решение пробовал? https://www.sql.ru/forum/actualutils.aspx?action=gotomsg&tid=1330938&msg=22233231
...
Рейтинг: 0 / 0
После выполнения CreateProcess зависаем на WaitForSingleObject
    #40020300
Zelius
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
segor,

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

Перенаправление вывода в файл
...
Рейтинг: 0 / 0
После выполнения CreateProcess зависаем на WaitForSingleObject
    #40020301
alekcvp
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
У меня как-то так сделано, ничего не подвисает:

Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
  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: Повырезал всё лишнее.
...
Рейтинг: 0 / 0
После выполнения CreateProcess зависаем на WaitForSingleObject
    #40020303
YuRock
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
wadman
Всё нормально
Ну я б не сказал.
Если ReadFile начнет возвращать False, или размер прочитанного окажется меньше ожидаемого - будет вечный цикл.
Каша-алгоритм это, а не всё нормально. Надежда только на везение.
...
Рейтинг: 0 / 0
После выполнения CreateProcess зависаем на WaitForSingleObject
    #40020305
segor
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Kazantsev Alexey
segor
Друзья, кто может удаленно помочь - напишите, пжалста, в телегу @khudiakov_s
Моя благодарность не будет иметь границ)) Сил уже нет...


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


Я его не осилил( Не хватает знаниев. Не компилируется.
...
Рейтинг: 0 / 0
После выполнения CreateProcess зависаем на WaitForSingleObject
    #40020325
Kazantsev Alexey
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
segor,

Какая у тебя версия Delphi?
...
Рейтинг: 0 / 0
После выполнения CreateProcess зависаем на WaitForSingleObject
    #40020346
segor
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Kazantsev Alexey
segor,

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


10.3
...
Рейтинг: 0 / 0
После выполнения CreateProcess зависаем на WaitForSingleObject
    #40020355
Dimitry Sibiryakov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
segorЯ его не осилил( Не хватает знаниев. Не компилируется.

Ну так прокачивай знания пока не осилишь.
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
После выполнения CreateProcess зависаем на WaitForSingleObject
    #40020357
Kazantsev Alexey
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
segor,

Упрощённый ExecuteProcess
Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
71.
72.
73.
74.
75.
76.
77.
78.
79.
80.
81.
82.
83.
84.
85.
86.
87.
88.
89.
90.
91.
92.
93.
94.
95.
96.
97.
98.
99.
100.
101.
102.
103.
104.
105.
106.
107.
108.
109.
110.
111.
112.
113.
114.
115.
116.
117.
118.
119.
120.
121.
122.
123.
124.
125.
126.
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.

...
Рейтинг: 0 / 0
После выполнения CreateProcess зависаем на WaitForSingleObject
    #40020533
Fr0sT-Brutal
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Да возьмите у джедаев и все
...
Рейтинг: 0 / 0
После выполнения CreateProcess зависаем на WaitForSingleObject
    #40020567
Фотография makhaon
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
возьмите готовое и многократно опробованное решение в жедаях. так вам нравится ковыряться в велосипедах, которые уже лет 20 как отлично решены
...
Рейтинг: 0 / 0
После выполнения CreateProcess зависаем на WaitForSingleObject
    #40020578
segor
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Спасибо. Покурим с джедаями)
...
Рейтинг: 0 / 0
После выполнения CreateProcess зависаем на WaitForSingleObject
    #40020579
segor
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Kazantsev Alexey
segor,

Упрощённый ExecuteProcess
Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
71.
72.
73.
74.
75.
76.
77.
78.
79.
80.
81.
82.
83.
84.
85.
86.
87.
88.
89.
90.
91.
92.
93.
94.
95.
96.
97.
98.
99.
100.
101.
102.
103.
104.
105.
106.
107.
108.
109.
110.
111.
112.
113.
114.
115.
116.
117.
118.
119.
120.
121.
122.
123.
124.
125.
126.
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.



Спасибо )
...
Рейтинг: 0 / 0
После выполнения CreateProcess зависаем на WaitForSingleObject
    #40020700
Фотография makhaon
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
segor
Спасибо. Покурим с джедаями)

Что бы долго не искать:
https://github.com/project-jedi/jcl/blob/9d89903a2ee38fa72be47df433c46c7747ba4025/jcl/source/common/JclSysUtils.pas#L501
...
Рейтинг: 0 / 0
45 сообщений из 45, показаны все 2 страниц
Форумы / Delphi [игнор отключен] [закрыт для гостей] / После выполнения CreateProcess зависаем на WaitForSingleObject
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]