Неименованные трубы, как я понял, поддерживают только блокирующие операции, что со стороны ББ не допустимо.
Попробовал сделать с именованными, но застрял в трубе при открытии её на запись. Кто подскажет?
## Код:
```
MODULE TestStdToLog;

  IMPORT
    WinApi, Dialog, Strings;

  CONST
    INVALID_HANDLE_VALUE = -1;
    pipeName = "\\.\pipe\stdoutToBBLog";
    
  VAR
    read, write: WinApi.HANDLE;
    ovrl: WinApi.OVERLAPPED;
    
  PROCEDURE ShowWinErr (IN act: ARRAY OF CHAR);
    VAR  msg: ARRAY 512 OF CHAR; err, res: INTEGER;
  BEGIN
    err := WinApi.GetLastError();
    res := WinApi.FormatMessageW(
      WinApi.FORMAT_MESSAGE_FROM_SYSTEM,
      0, err, 0, msg, LEN(msg), NIL
      );
    IF res = 0 THEN  (* Описание ошибки не получено *)
      Strings.IntToString(err, msg); msg := msg + " (WinAPI-код ошибки)"
    END;
    Dialog.ShowParamMsg("Ошибка при ^0: ^1", act, msg, "")
  END ShowWinErr;
  
  PROCEDURE Uninstall;
    VAR  res: INTEGER;
  BEGIN
    IF write # INVALID_HANDLE_VALUE THEN
      res := WinApi.CloseHandle(write);
      write := INVALID_HANDLE_VALUE;
      IF res = 0 THEN ShowWinErr("CloseHandle(write)") END
    END;
    IF read # INVALID_HANDLE_VALUE THEN
      res := WinApi.CloseHandle(read);
      read := INVALID_HANDLE_VALUE;
      IF res = 0 THEN ShowWinErr("CloseHandle(read)") END
    END;
    (* An instance of a named pipe is always deleted when the last handle to the instance of the named pipe is closed. *)
    IF ovrl.hEvent # INVALID_HANDLE_VALUE THEN
      res := WinApi.CloseHandle(ovrl.hEvent);
      ovrl.hEvent := INVALID_HANDLE_VALUE;
      IF res = 0 THEN ShowWinErr("CloseHandle(ovrl.hEvent)") END
    END
  END Uninstall;

  PROCEDURE CreatePipe;
    VAR  res: INTEGER;
  BEGIN
    res := WinApi.CreateNamedPipe(
      pipeName,
      ORD({WinApi.PIPE_ACCESS_INBOUND} + WinApi.FILE_FLAG_OVERLAPPED),
      WinApi.PIPE_TYPE_BYTE + WinApi.PIPE_READMODE_BYTE + WinApi.PIPE_WAIT,
      1,
      1024,  (* ? *)
      1024,  (* ? *)
      1,  (* ? *)
      NIL);
    IF res # INVALID_HANDLE_VALUE THEN
      read := res
    ELSE
      ShowWinErr("CreateNamedPipe")
    END
  END CreatePipe;

  PROCEDURE ConnectPipe;
    VAR  res: INTEGER; ovrl: WinApi.OVERLAPPED;
  BEGIN
    (* If hNamedPipe was opened with FILE_FLAG_OVERLAPPED, the lpOverlapped parameter must not be NULL. It must point to a valid OVERLAPPED structure. If hNamedPipe was opened with FILE_FLAG_OVERLAPPED and lpOverlapped is NULL, the function can incorrectly report that the connect operation is complete.

If hNamedPipe was created with FILE_FLAG_OVERLAPPED and lpOverlapped is not NULL, the OVERLAPPED structure pointed to by lpOverlapped must contain a handle to a manual-reset event object (which the server can create by using the CreateEvent function). *)
    ovrl.hEvent := WinApi.CreateEvent(NIL, WinApi.TRUE, WinApi.FALSE, NIL);
    IF ovrl.hEvent # 0 THEN
      res := WinApi.ConnectNamedPipe(read, ovrl);
      IF res = 0 THEN ShowWinErr("ConnectNamedPipe") END
    ELSE
      ShowWinErr("CreateEvent")
    END
  END ConnectPipe;

  PROCEDURE Install;
    VAR  res: INTEGER;
  BEGIN
    read := INVALID_HANDLE_VALUE; write := INVALID_HANDLE_VALUE;
    CreatePipe;
    IF read # INVALID_HANDLE_VALUE THEN
      ConnectPipe;
      
      res := WinApi.CreateFile(
        pipeName,
        WinApi.GENERIC_WRITE,
        {},
        NIL,
        WinApi.OPEN_EXISTING,  (* ? *)
        WinApi.FILE_ATTRIBUTE_NORMAL,  (* ? *)
        0
        );
      
      IF res = INVALID_HANDLE_VALUE THEN
        ShowWinErr("CreateFile")
      ELSE  (* res # INVALID_HANDLE_VALUE *)
        write := res
      END
    END
  END Install;
  
BEGIN
  Install
CLOSE
  Uninstall
END TestStdToLog.

^Q "Kernel.LoadMod('TestStdToLog')"
```
