powered by simpleCommunicator - 2.0.61     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / Delphi [игнор отключен] [закрыт для гостей] / Нужно получить значение из канала PIPE, но когда оно пустое, пишет ошибку Канал закрыт
25 сообщений из 27, страница 1 из 2
Нужно получить значение из канала PIPE, но когда оно пустое, пишет ошибку Канал закрыт
    #39926748
yemets63
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Нужно получить значение из канала PIPE, но когда оно пустое, пишет ошибку Канал закрыт

Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
      Stream := TMemoryStream.Create;
      try
        if Windows.ReadFile(PipeRead, Buffer, 16382, NumberOfBytesRead, nil) then
        begin
          Stream.Write(PipeRead, NumberOfBytesRead);
          Stream.Position := 0;
          AErrors.LoadFromStream(Stream,TEncoding.GetEncoding(GetOEMCP));
        end;
      finally
        Stream.Free;
        CloseHandle(PipeRead);
      end;



если в Буфер что то приходит, и размер NumberOfBytesRead не равен 0, GetLastError = 0
если в Буфере пусто, и размер NumberOfBytesRead = 0, GetLastError = 109 - Канал закрыт

сам PipeRead имеет только номер процесса

как проверить перед выполнением Windows.ReadFile(PipeRead, Buffer, 16382, NumberOfBytesRead, nil) если результата не будет, то не выполнять вышеприведенный код

очень не красиво в finally end ставить SetLastError(0)
...
Рейтинг: 0 / 0
Нужно получить значение из канала PIPE, но когда оно пустое, пишет ошибку Канал закрыт
    #39926751
Dimitry Sibiryakov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
yemets63Stream.Write(PipeRead, NumberOfBytesRead);

Это что за бред?
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
Нужно получить значение из канала PIPE, но когда оно пустое, пишет ошибку Канал закрыт
    #39926863
Фотография _Vasilisk_
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
yemets63
очень не красиво в finally end ставить SetLastError(0)
А зачем его ставить? Это раз. А второе зачем проверять GetLastError, если функция вернула True?
...
Рейтинг: 0 / 0
Нужно получить значение из канала PIPE, но когда оно пустое, пишет ошибку Канал закрыт
    #39926873
Фотография makhaon
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
yemets63,

ты же как-то трубу у себя открываешь? тут же самого главного - кода открытия - нет, но зачем то есть код чтения, к тому же неверный. вот на открытии и проверяй. открылась труба - значит ок. нет - значит трубы нет.
...
Рейтинг: 0 / 0
Нужно получить значение из канала PIPE, но когда оно пустое, пишет ошибку Канал закрыт
    #39926875
Мимопроходящий
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
14.02.2020 18:49, makhaon пишет:
> открылась труба - значит ок. нет - значит трубы нет.

при открытии да, но канал может сдохнуть и в процессе чтения.
результат нужно проверять всегда.
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
Нужно получить значение из канала PIPE, но когда оно пустое, пишет ошибку Канал закрыт
    #39926891
Фотография _Vasilisk_
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Мимопроходящий
результат нужно проверять всегда.
Но не GetLastError
...
Рейтинг: 0 / 0
Нужно получить значение из канала PIPE, но когда оно пустое, пишет ошибку Канал закрыт
    #39927405
yemets63
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
_Vasilisk_,

код достаточно стаднтартный, запись текста из консоли, взят из Интернета еще за долго до меня.
я пробежался и особо ни чего не придумал, разве только заменить чтение Pipe в поток через функцию.

и так по тексту

сначала
CreatePipe(PipeOutputRead, PipeOutputWrite, @SecurityAttr, 0);
CreatePipe(PipeErrorsRead, PipeErrorsWrite, @SecurityAttr, 0);

потом процесс

if CreateProcess( nil, CommandMem, nil, nil, True, CreationFlags, nil, nil, StartupInfo, ProcessInfo) then
begin


GetExitCodeProcess(ProcessInfo.hProcess, AProcessExitCode);
если процесс пошел,
while AProcessExitCode = STILL_ACTIVE do
begin

далее получение текста из консоли
Stream := TMemoryStream.Create;
try
while true do
begin
succeed := ReadFile(PipeOutputRead, Buffer, BufferSizeText, NumberOfBytesRead, nil);
if not succeed then break;
Stream.Write(Buffer, NumberOfBytesRead);
end;
Stream.Position := 0;
AOutput.LoadFromStream(Stream,TEncoding.GetEncoding(GetOEMCP));
finally
Stream.Free;
end;
Result := True;
end:

end else
begin
Result := False;
end;

в конце закрытие и выдача результатов

ALastOSError := GetLastError;
GetExitCodeProcess(ProcessInfo.hProcess, AProcessExitCode);
CloseHandle(ProcessInfo.hProcess);

Result false или true если файл выполнился то true
если файл выполнился то - GetExitCodeProcess(ProcessInfo.hProcess, AProcessExitCode) = 0
а вот GetLastError равен 0, пока не начинаю закрывать каналы, и притом возврат код сообщения, например 109 - канал закрыт. следующий шаг после 109 будет логично 87, так как параметры уже получиться нельзя, но это уже не интересно, так как результат из pipe получен AOutput и / или AError


проблема с тестировщиками, им не нравится,
мы протестировали, результат при наличии файлов и правильных команд даже с перенаправлением всегда есть.
...
Рейтинг: 0 / 0
Нужно получить значение из канала PIPE, но когда оно пустое, пишет ошибку Канал закрыт
    #39927460
Dimitry Sibiryakov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
yemets63код достаточно стаднтартный, запись текста из консоли, взят из Интернета еще за долго до меня.

Код достаточно бредовый, сразу видно что из интернета. Пора отказаться от отмазки "задолго
до меня" и таки переписать его правильно.
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
Нужно получить значение из канала PIPE, но когда оно пустое, пишет ошибку Канал закрыт
    #39927468
yemets63
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dimitry Sibiryakov,

ни фига не отмазка, код с 2014-го лежит, приписка автора есть, который когда то был до нас

но по сути, я сделал почти тоже самое, до его кода, есть какие то свежие решения?
...
Рейтинг: 0 / 0
Нужно получить значение из канала PIPE, но когда оно пустое, пишет ошибку Канал закрыт
    #39927471
Dimitry Sibiryakov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
yemets63есть какие то свежие решения?

В данном случае нужны не "свежие", а правильные решения. Как минимум - избавиться от
Stream и начать ловить завершение приложения именно по закрытию трубки, а не GetExitCode.
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
Нужно получить значение из канала PIPE, но когда оно пустое, пишет ошибку Канал закрыт
    #39927479
Мимопроходящий
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
17.02.2020 13:57, Dimitry Sibiryakov пишет:
> начать ловить завершение приложения именно по закрытию трубки, а не GetExitCode.

не-а.
каноны велят отделять мух от котлет.
закрытие трубы всё таки не всегда тождественно завершению приложения.

Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
Нужно получить значение из канала PIPE, но когда оно пустое, пишет ошибку Канал закрыт
    #39927483
Dimitry Sibiryakov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Мимопроходящийзакрытие трубы всё таки не всегда тождественно завершению приложения.

"Чо?"
Кто ж её закроет-то? И самый главный вопрос: а что делать с приложением, которое её таки
закрыло?
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
Нужно получить значение из канала PIPE, но когда оно пустое, пишет ошибку Канал закрыт
    #39927488
Мимопроходящий
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
при обломе трубы жди СиглОбжект.
если WAIT_OBJECT_0, получай ЭкзитПроцессКоде
если WAIT_FAILED, получай ЛастЕгор

"А кулаками махать любой дурак умеет." (С)
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
Нужно получить значение из канала PIPE, но когда оно пустое, пишет ошибку Канал закрыт
    #39927493
Фотография makhaon
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
yemets63,

готовая реализация не подойдет? в жедаях например:
https://github.com/project-jedi/jcl/blob/3a1b1681dfc2e461c02e44255a60b582a6e44b35/jcl/source/windows/JclMiscel.pas#L66
...
Рейтинг: 0 / 0
Нужно получить значение из канала PIPE, но когда оно пустое, пишет ошибку Канал закрыт
    #39927498
Мимопроходящий
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
17.02.2020 14:31, makhaon пишет:
> готовая реализация не подойдет? в жедаях например:

мощно!
Код: pascal
1.
2.
3.
4.
function WinExec32AndRedirectOutput(const Cmd: string; var Output: string; RawOutput: Boolean): Cardinal;
begin
  Result := Execute(Cmd, Output, RawOutput);
end;


дайте две!
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
Нужно получить значение из канала PIPE, но когда оно пустое, пишет ошибку Канал закрыт
    #39927625
yemets63
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
джеди не пойдет,

WinExec32AndRedirectOutput - нет, ... "Герои не ищут легких путей",

хочу правильных решений и чем больше, тем лучше,
и так что сделать со Stream?
...
Рейтинг: 0 / 0
Нужно получить значение из канала PIPE, но когда оно пустое, пишет ошибку Канал закрыт
    #39927628
Мимопроходящий
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
стрим в данном случае нахрен не нужен.
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
Нужно получить значение из канала PIPE, но когда оно пустое, пишет ошибку Канал закрыт
    #39927635
Zelius
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
yemets63,

может подойдет
Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
  function TryReadFromPipe( aPipe: THandle; out aBytes: TBytes): Boolean;
  var
    TotalBytesAvailable: DWORD;
    dwRead: Cardinal;
  begin
    SetLength( aBytes, 0);
    Result := False;
    Win32Check( PeekNamedPipe( aPipe, nil, 0, nil, @TotalBytesAvailable, nil));
    if TotalBytesAvailable <> 0 then
    begin
      SetLength( aBytes, TotalBytesAvailable);
      Win32Check( ReadFile( aPipe, Pointer(aBytes)^, TotalBytesAvailable, dwRead, nil));
      Result := True;
    end;
  end;



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

Очередной нагугленный код, который решает не совсем ту задачу, которая стоит. Вот так сон
разума и рождает чудовищ.
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
Нужно получить значение из канала PIPE, но когда оно пустое, пишет ошибку Канал закрыт
    #39927730
Фотография makhaon
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Мимопроходящий,

что не так?

yemets63,

ну ок, делай свой очередной велосипед. Безумству храбрых поем мы славу!
...
Рейтинг: 0 / 0
Нужно получить значение из канала PIPE, но когда оно пустое, пишет ошибку Канал закрыт
    #39927788
yemets63
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
makhaon


ну ок, делай свой очередной велосипед. Безумству храбрых поем мы славу!


полностью согласен, но политика местной партии напрягает, и вынуждает начать все с квадратных колес, были решения проще и все рабочие. но примерно раз в год когото прёт, и приходится придумывать велосипеды, которые ездят боком
...
Рейтинг: 0 / 0
Нужно получить значение из канала PIPE, но когда оно пустое, пишет ошибку Канал закрыт
    #39927809
kealon(Ruslan)
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dimitry Sibiryakov

Мимопроходящийзакрытие трубы всё таки не всегда тождественно завершению приложения.

"Чо?"
Кто ж её закроет-то? И самый главный вопрос: а что делать с приложением, которое её таки
закрыло?
её вызывающий должен закрывать, но никак не вызываемый
если по правильному, то вызываемому приложению даётся только дубликат хэндла - хоть зазакрывайся

другое дело, что обычно чтение делают в другом потоке в бокирующем режиме и закрывают Pipe когда убеждаются, что вызываемое приложение завершено, естественно вывалится ошибка на чтении
...
Рейтинг: 0 / 0
Нужно получить значение из канала PIPE, но когда оно пустое, пишет ошибку Канал закрыт
    #39927873
yemets63
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
расскидал стандартный текст из интернета, о чем речь шла сначала по своему, протестировал сам, сделал кучу прерываний, убивал потоки и разрушал файлы, реакция есть.
до сих пор не понятно, почему когда нет ошибки и буфер пуст показывает что канал закрыт, номер 109, в итоге я его тупо ставлю в 0.
ошибки при процессах если не создавать нет.

короче отдал на тестирование, через пару дней будет ответ.
...
Рейтинг: 0 / 0
Нужно получить значение из канала PIPE, но когда оно пустое, пишет ошибку Канал закрыт
    #39927877
Zelius
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
yemets63,

MSDNIf an anonymous pipe is being used and the write handle has been closed, when ReadFile attempts to read using the pipe's corresponding read handle, the function returns FALSE and GetLastError returns ERROR_BROKEN_PIPE.
...
Рейтинг: 0 / 0
Нужно получить значение из канала PIPE, но когда оно пустое, пишет ошибку Канал закрыт
    #39927878
Фотография makhaon
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
yemets63,

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

вот ссылка прямо на сам код, а то вместе с Мимипроходящим так мимо и пройдете

https://github.com/project-jedi/jcl/blob/bde454905aac7f961350e5c36af5ad0a4713963b/jcl/source/common/JclSysUtils.pas#L2993
...
Рейтинг: 0 / 0
25 сообщений из 27, страница 1 из 2
Форумы / Delphi [игнор отключен] [закрыт для гостей] / Нужно получить значение из канала PIPE, но когда оно пустое, пишет ошибку Канал закрыт
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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