Announcement

Collapse
No announcement yet.

Beginner's question about "pipes."

Collapse
X
  • Filter
  • Time
  • Show
Clear All
new posts

  • #21
    Edward,
    I don't have a lot of time. Below is a messy (quickly thrown together) example.
    I installed et_chess (http://eric.triki.pagesperso-orange.fr/frames_en.html) in the directory c:\chess.
    As posted, the following code correctly signs on to the chess engine and receives a response.
    I hope it's enough to get you started.

    Paul.
    Code:
    'PBCC6 program
    #DIM ALL
    #INCLUDE "win32api.inc"
    FUNCTION PBMAIN () AS LONG
    LOCAL Junk AS LONG
    LOCAL hReadSTDINPipe, hWriteSTDINPipe AS LONG
    LOCAL hReadSTDOUTPipe, hWriteSTDOUTPipe AS LONG
    LOCAL SecurityAttrib AS SECURITY_ATTRIBUTES
    LOCAL DataToSend AS STRING
    LOCAL DataReceived AS STRING*4096
    LOCAL num AS LONG
    LOCAL si AS StartUpInfo
    
    LOCAL pi AS Process_Information
    LOCAL r AS LONG
    
    'a default descriptor
    SecurityAttrib.nLength = SIZEOF(SecurityAttrib)
    SecurityAttrib.lpSecurityDescriptor = 0 'VARPTR(sd)
    SecurityAttrib.bInheritHandle = -1
    
    'create STDIN pipe
    Junk = CreatePipe(hReadSTDINPipe, hWriteSTDINPipe,  SecurityAttrib,4096)
    
    PRINT "CreatePipe returned";junk
    PRINT ERR,ERROR$
    
    
    
    'create STDOUT pipe
    Junk = CreatePipe(hReadSTDOUTPipe, hWriteSTDOUTPipe, SecurityAttrib,4096)
    
    PRINT "CreatePipe returned";junk
    PRINT ERR,ERROR$
    
    
    GetStartupInfo(si)
    si.dwFlags = %STARTF_USESTDHANDLES OR %STARTF_USESHOWWINDOW
    si.wShowWindow = %SW_HIDE
    si.hStdOutput = hWriteSTDOUTPipe
    si.hStdError = hWriteSTDOUTPipe
    si.hStdInput = hReadSTDINPipe
    
    PRINT "si.cb=";si.cb
    
    
    junk = CreateProcess("C:\chess\et_chess.exe", "C:\chess\et_chess.exe ", BYVAL 0, BYVAL 0, BYVAL -1, BYVAL 0, BYVAL 0, BYVAL 0, si, pi)
    
    PRINT "CreateProcess returned";junk
    
    
    DataToSend="xboard"+$CRLF
    junk = writefile(hWriteSTDINPipe, STRPTR(DataToSend),LEN(DataToSend), num , BYVAL 0)
    'PRINT "WriteFile returned ";junk
    
    
    DataToSend="protover 1" +$CRLF
    junk = writefile(hWriteSTDINPipe, STRPTR(DataToSend),LEN(DataToSend), num , BYVAL 0)
    'PRINT "WriteFile returned ";junk
    
    
    
    SLEEP 1000   'give the engine time to respond
    junk = readfile(hReadSTDOUTPipe, VARPTR(DataReceived),LEN(DataReceived), num , BYVAL 0)
    'PRINT "ReadFile returned ";junk
    
    PRINT "DataReceived=";LEFT$(DataReceived,num)
    PRINT
    PRINT
    PRINT
    PRINT
    PRINT
    PRINT
    
    
    
    DO
        INPUT "Move?",DataToSend
        DataToSend = DataToSend + $CRLF
    
    junk = writefile(hWriteSTDINPipe, STRPTR(DataToSend ),LEN(DataToSend ), num , BYVAL 0)
    PRINT "WriteFile returned ";junk
    PRINT "num=";num
    IF num <> LEN(DataToSend ) THEN PRINT "different";num,LEN(DataToSend )
    
    
    SLEEP 1000   'give the engine time to respond
    junk = readfile(hReadSTDOUTPipe, VARPTR(DataReceived),100, num , BYVAL 0)
    PRINT "ReadFile returned ";junk
    
    PRINT "DataReceived=";LEFT$(DataReceived,num)
    PRINT
    PRINT
    PRINT
    PRINT
    PRINT
    PRINT
    PRINT
    
    
    PRINT "err=";ERR,ERROR$
    
    LOOP UNTIL DataToSend =""
    
    
    END FUNCTION

    Comment


    • #22
      FWIW....
      Code:
      junk = writefile(hWriteSTDINPipe, STRPTR(DataToSend ),LEN(DataToSend ), num , BYVAL 0)
      
      SLEEP 1000   'give the engine time to respond
      junk = readfile(hReadSTDOUTPipe, VARPTR(DataReceived),100, num , BYVAL 0)
      ...
      SDK doc:
      The ReadFile function returns when one of the following conditions is met: a write operation completes on the write end of the pipe, the number of bytes requested has been read, or an error occurs.
      SO.... you don't really need to sleep, Readfile() will return when the engine has completed writing its response.

      Very nice demo BTW.. very straightforward.

      MCM
      Michael Mattias
      Tal Systems Inc.
      Racine WI USA
      mmattias@talsystems.com
      http://www.talsystems.com

      Comment


      • #23
        Michael,
        multiple lines are being returned in response to each move and some of those lines take a while to return, I assume the program is thinking about it and reporting back the best line of analysis so far. Only the last line appears to be the chosen move.

        If the program doesn't wait then it'll only get the first line of analysis.

        As it stands, the number of bytes retrieved by ReadFile (100) is too small and needs to be increased considerably to maybe 2000 or more. Some of the lines of analysis go on for a long time!


        A better way would be to retrieve individual lines until one of them starts with "move" because that's is the last line, the chosen move, but I did say it was messy. I don't even close the handles of the pipes .. .

        Paul.

        Comment


        • #24
          What's messy about:
          Code:
          DO
          junk = readfile(hReadSTDOUTPipe, VARPTR(DataReceived),100, num , BYVAL 0)
          LOOP UNTIL Left$(DataREceived,4) = "move"
          --
          [URL="http://www.camcopng.com"]CAMCo - Applications Development & ICT Consultancy[/URL][URL="http://www.hostingpng.com"]
          PNG Domain Hosting[/URL]

          Comment


          • #25
            Everyone,

            Thank you. Everyone's been very helpful. I have a lot to look over now, and a lot to learn from. You guys are the greatest.

            I'm busy this weekend but early next week I can take a closer look at all of this. I think I've got enough to get me started, and that's all I needed.

            (Oh, and if I previously told the engine to analyze only, it will never "move." It will analyze the position forever, or until told to stop.)

            Comment


            • #26
              Well, if you want the return back "a line at a time" AND assuming each line so returned is terminated by CRLF, you should be able to...

              Code:
                LOCAL hPB AS LONG 
               
                hPB = FREEFILE 
                OPEN  HANDLE hReadStdOutPipe FOR INPUT AS hPB 
                LINE INPUT #hPB, ALineOfdata$
               .....
              ...but I think using sequential access ("FOR INPUT") there might be some bigtime 'end of file' controls issues. (e.g., you can't close/reopen because the file pointer goes back to zero on the reopen).

              I'd probably just query the length of the data (there must be a way to do that), get it all and parse it into lines myself.

              Well, maybe not. I'd have to play with it.

              All in all, this is a pretty interesting little programming challenge.

              MCM
              Michael Mattias
              Tal Systems Inc.
              Racine WI USA
              mmattias@talsystems.com
              http://www.talsystems.com

              Comment


              • #27
                I'm not a chess player so I haven't gone much further with this.
                The program below sorts out various problems with the one posted earlier.
                It still doesn't do full error checking that reads and writes and opens all worked.
                It doesn't respond fully to the potential replies from the chess engine (mostly because I can't be bothered to read through the full spec!)

                It formats the text output better (so it can be read!)
                It appears to accept all valid and invalid moves and responds accordingly but if you type in garbage (something the chess engine doesn't understand as a possible move) then it'll hang on the ReadFile line because, as it stands, it expects the final reply from the chess engine to include the word "move".

                It's written for ET_chess engine (http://eric.triki.pagesperso-orange.fr/frames_en.html) I don't know if it'll work with anything else, I haven't tried.
                It expects ET_chess to be installed in the directory c:\chess but that could be changed easily enough.

                It appears to work reliably with PBCC5 and 6.

                I'm sure Edward will post a much more usable program when he gets around to it.

                Paul.



                Code:
                'PBCC  program
                'attempt to inteface via pipes with a chess engine
                #BREAK ON
                '#COMPILE CON
                #DIM ALL
                #INCLUDE "win32api.inc"
                
                
                FUNCTION PBMAIN () AS LONG
                
                LOCAL hReadSTDINPipe, hWriteSTDINPipe       AS LONG
                LOCAL hReadSTDOUTPipe, hWriteSTDOUTPipe     AS LONG
                LOCAL num, Junk, r, NumLines   AS LONG
                LOCAL SecurityAttrib    AS SECURITY_ATTRIBUTES
                LOCAL DataToSend        AS STRING
                LOCAL DataReceived      AS STRING*4096
                LOCAL Residue, ThisLine AS STRING
                LOCAL si    AS StartUpInfo
                LOCAL pi    AS Process_Information
                
                
                'a default descriptor
                SecurityAttrib.nLength = SIZEOF(SecurityAttrib)
                SecurityAttrib.lpSecurityDescriptor = 0
                SecurityAttrib.bInheritHandle = -1
                
                'create STDIN pipe
                Junk = CreatePipe(hReadSTDINPipe, hWriteSTDINPipe,  SecurityAttrib,4096)
                PRINT "CreatePipe returned";junk
                
                'create STDOUT pipe
                Junk = CreatePipe(hReadSTDOUTPipe, hWriteSTDOUTPipe, SecurityAttrib,0)
                PRINT "CreatePipe returned";junk
                
                PRINT ERR,ERROR$
                
                'sort out the STDIN abd STDOUIT redirection for the new process
                GetStartupInfo(si)
                si.dwFlags = %STARTF_USESTDHANDLES OR %STARTF_USESHOWWINDOW
                si.wShowWindow = %SW_HIDE
                si.hStdOutput = hWriteSTDOUTPipe
                si.hStdError = hWriteSTDOUTPipe
                si.hStdInput = hReadSTDINPipe
                
                
                'Create the chess engine process. Here we're using ET_chess. The h64 specifies the maximum RAM to be used by the chess engine as 64MB
                junk = CreateProcess("C:\chess\et_chess.exe", "C:\chess\et_chess.exe h64", BYVAL 0, BYVAL 0, BYVAL -1, BYVAL 0, BYVAL 0, BYVAL 0, si, pi)
                PRINT "CreateProcess returned";junk
                
                
                DataToSend="xboard" + $CRLF      'required first line to send to ET_Chess. There is no response to look for
                junk = writefile(hWriteSTDINPipe, BYVAL STRPTR(DataToSend),LEN(DataToSend), num , BYVAL 0)
                'PRINT "WriteFile returned ";junk
                
                
                DataToSend="protover 1" + $CRLF     'required second line to send to ET_Chess
                junk = writefile(hWriteSTDINPipe, BYVAL STRPTR(DataToSend),LEN(DataToSend), num , BYVAL 0)
                'PRINT "WriteFile returned ";junk
                
                
                SLEEP 1000   'give the engine time to respond
                junk = readfile(hReadSTDOUTPipe, BYVAL VARPTR(DataReceived),LEN(DataReceived), num , BYVAL 0)
                PRINT "ReadFile returned ";junk
                
                PRINT "DataReceived=";LEFT$(DataReceived,num) 'this is the response to show you've signed on to the chess engine
                PRINT
                PRINT
                PRINT
                PRINT
                PRINT
                PRINT
                
                
                'Now play the game
                DO
                    INPUT "Move?",DataToSend
                    DataToSend = DataToSend + $CRLF
                
                    junk = writefile(hWriteSTDINPipe, BYVAL STRPTR(DataToSend ),LEN(DataToSend ), num , BYVAL 0)
                    PRINT "WriteFile returned ";junk
                    PRINT "num=";num
                    IF num <> LEN(DataToSend ) THEN PRINT "different";num,LEN(DataToSend )
                
                    IF LEFT$(DataToSend,4) = "quit" THEN
                        EXIT DO
                    END IF
                
                    NumLines=1
                    Residue = ""
                
                    DO
                        junk = readfile(hReadSTDOUTPipe, BYVAL VARPTR(DataReceived),LEN(DataReceived), num , BYVAL 0)
                        Residue +=  LEFT$(DataReceived,num)
                
                        WHILE INSTR(Residue,$CRLF)
                            ThisLine = EXTRACT$(Residue,$CRLF)
                            PRINT FORMAT$(Numlines,"* ####");":";ThisLine
                            INCR NumLines
                            Residue = REMAIN$(Residue, $CRLF)
                
                        WEND
                
                    LOOP UNTIL INSTR(ThisLine,"move")
                
                    BEEP
                
                    PRINT "err=";ERR,ERROR$
                    PRINT
                    PRINT "thisline= ";thisline
                    PRINT
                
                LOOP
                
                'All done, just tidy up then exit
                closehandle(hReadSTDOUTPipe)
                closehandle(hWriteSTDOUTPipe)
                closehandle(hReadSTDINPipe)
                closehandle(hWriteSTDINPipe)
                
                
                END FUNCTION

                Comment


                • #28
                  Stuart
                  What's messy about: ..
                  ReadFile will return when any valid characters are present, it doesn't wait for full lines.

                  If the program is waiting at ReadFile for data and the chess engine replies with "move a7a6" then as soon at the "m" of "move" enters the pipe the ReadFile takes the "m", assigns it to DataReceived and continues program execution.

                  "m" <> "move" so the check will fail, the loop will iterate and by now the remainder of the data is waiting so ReadFile will immediately return with the remaining characters "ove a7a6".

                  "ove " <> "move" so the loop iterates again and stalls because the chess engine is finished replying but the reply was misunderstood as it was broken up in the process.

                  Paul.

                  Comment


                  • #29
                    In that case, you need to buffer DataReceived and split out individual lines based on line terminators or whatever.
                    sample aircode:
                    Code:
                    DO
                       'get a line
                       DO
                          junk = readfile(hReadSTDOUTPipe, BYVAL VARPTR(DataReceived),LEN(DataReceived), num , BYVAL 0)
                          strBuffer =  strBuffer &  DataReceived
                       Loop until instr(strBuffer,Chr$(13,10)
                       'Save the line in an array
                       incr Linenum
                       myPtr = Instr(strBuffer,Chr$(13,10))
                       strLines(Linenum) = Left$(strBuffer,myPtr - 1)
                       'remove the saved line from the buffer
                       strBuffer = mid$(strBuffer,myPtr + 2) 
                    LOOP Until left$(strLines(Linenum),4) = "move"
                    --
                    [URL="http://www.camcopng.com"]CAMCo - Applications Development & ICT Consultancy[/URL][URL="http://www.hostingpng.com"]
                    PNG Domain Hosting[/URL]

                    Comment


                    • #30
                      ReadFile will return when any valid characters are present, it doesn't wait for full lines.
                      That's not what the doc says.

                      Repeating from Post #22 this thread:
                      The ReadFile function returns when one of the following conditions is met: a write operation completes on the write end of the pipe, the number of bytes requested has been read, or an error occurs.
                      What we don't know is, does the chess engine return multiple lines as multiple writes of one CRLF-terminated line per write? Or does it write all lines as one big block of data with embedded CRLF? Or maybe it writes responses a character at a time?

                      Had I written the engine, I'd probably write one (1) multiple line (CRLF-delimited) string per response, precisely to make it easy for any 'player software' to exploit ReadFile()'s behavior - but I did not write it so I'd have to look for it in the doc (a dream?) or {gasp} try it.
                      Last edited by Michael Mattias; 15 Jul 2011, 08:55 AM.
                      Michael Mattias
                      Tal Systems Inc.
                      Racine WI USA
                      mmattias@talsystems.com
                      http://www.talsystems.com

                      Comment


                      • #31
                        Michael,
                        that's what I thought when I started it but that's not how it appears to work.

                        If I print off just the individual lines returned by ReadFile after making a move I get the following:
                        Code:
                        Line: 37      1
                        
                        Line: 38      0   1    93   864019  + d5 2/20 (922K/s)
                        
                        Line: 39      m
                        
                        Line: 40      ove d7d5
                        I suppose it's possible that the chess engine is sending out "m" and then "ove d7d5 {crlf}"

                        Paul.

                        Comment


                        • #32
                          > that's what I thought when I started it but that's not how it appears to work.

                          You obviously weren't in the room when the engine was written, either.

                          MCM
                          Michael Mattias
                          Tal Systems Inc.
                          Racine WI USA
                          mmattias@talsystems.com
                          http://www.talsystems.com

                          Comment


                          • #33
                            Hey Paul!
                            This old thread hits home on something I want to do - talk to a chess engine. In my case, I want my PBWin app (the Chess GUI I've posted recently) to do the talking.

                            I'm trying to start off with a simple, minimal demo of a PBWin app using pipes to talk to a simple console app - modifying your post #27 code for use in a PBWin app. It's supposed to just exchange strings on demand, rather than watch continuously as in your example.

                            I want to see the approach work before trying to use it with my chess GUI.

                            I've also written a very short PBCC app to be the other end of the communication link. That and my PBWin code are given below.

                            So far, pretty much all of it fails - no communication achieved!

                            Well, the PBCC app works by itself. But the PBWin code to make them talk together fails for reasons I don't yet understand. I hope that working more with the needed API will help me understand better why my code fails.

                            I do think I can see some things to try/fix, so I'll be working on it this week. However, if you could resurrect your thinking from 2011 and make any suggestions, that would be greatly appreciated! I apologize in advance for any abuse I may have made to your original code!


                            PBCC App:
                            Code:
                            #Compile Exe "gbconsole.exe"
                            #Include "win32api.inc"
                            Function PBMain
                               Local msg$, hConsole As Dword
                               hConsole = GetStdHandle(%Std_Input_Handle)
                               Print "Waiting ..."
                               Do
                                  StdIn Line msg$
                                  If msg$ = "x" Then Print "GoodBye ..." : Exit Do
                                  Print msg$
                                  Print "Waiting ..."
                               Loop
                            End Function
                            PBWin App:
                            Code:
                            'Compilable Example:
                            #Compile Exe  "gbboard"
                            #Dim All
                            %Unicode = 1
                            #Include "Win32API.inc"
                            
                            Enum Equates Singular
                               IDC_Get = 500
                               IDC_TextG
                               IDC_Send
                               IDC_TextS
                            End Enum
                            
                            Global hDlg                                  As Dword
                            Global hReadSTDINPipe, hWriteSTDINPipe       As Long
                            Global hReadSTDOUTPipe, hWriteSTDOUTPipe     As Long
                            Global num                                   As Long
                            Global SecurityAttrib                        As SECURITY_ATTRIBUTES
                            Global DataToSend                            As String
                            Global DataReceived                          As String*4096
                            Global si                                    As StartUpInfo
                            Global pi                                    As Process_Information
                            
                            Function PBMain() As Long
                               Dialog Font Default "Tahoma",12,1
                               Dialog New Pixels, 0, "gbBoard",300,300,300,150, %WS_OverlappedWindow To hDlg
                               Control Add Button, hDlg, %IDC_Get,"Get", 10,10,75,30
                               Control Add TextBox, hDlg, %IDC_TextG, "<empty>", 10,50,100,25
                               Control Add Button, hDlg, %IDC_Send,"Send", 140,10,50,25
                               Control Add TextBox, hDlg, %IDC_TextS, "<command>", 140,50,100,25
                               Dialog Show Modal hDlg Call DlgProc
                            End Function
                            
                            CallBack Function DlgProc() As Long
                               Select Case Cb.Msg
                                  Case %WM_InitDialog
                                     CreatePipes
                                  Case %WM_Command
                                     Select Case Cb.Ctl
                                        Case %IDC_Get
                                           readfile(hReadSTDOUTPipe, ByVal VarPtr(DataReceived),Len(DataReceived), num , ByVal 0)
                                           Control Set Text hDlg, %IDC_TextG, DataReceived
                                        Case %IDC_Send
                                           Control Get Text hDlg, %IDC_TextS To DataToSend
                                           DataToSend += $CrLf
                                           writefile(hWriteSTDINPipe, ByVal StrPtr(DataToSend),Len(DataToSend), num , ByVal 0)
                                     End Select
                                  Case %WM_Destroy
                                     closehandle(hReadSTDOUTPipe)
                                     closehandle(hWriteSTDOUTPipe)
                                     closehandle(hReadSTDINPipe)
                                     closehandle(hWriteSTDINPipe)
                               End Select
                            End Function
                            
                            Sub CreatePipes
                              'default security descriptor
                               SecurityAttrib.nLength = SizeOf(SecurityAttrib)
                               SecurityAttrib.lpSecurityDescriptor = 0
                               SecurityAttrib.bInheritHandle = -1
                               CreatePipe(hReadSTDINPipe, hWriteSTDINPipe,  SecurityAttrib,4096) 'create STDIN pipe
                               CreatePipe(hReadSTDOUTPipe, hWriteSTDOUTPipe, SecurityAttrib,0)   'create STDOUT pipe
                            
                               'sort out the STDIN abd STDOUIT redirection for the new process
                               GetStartupInfo(si)
                               si.dwFlags = %STARTF_USESTDHANDLES Or %STARTF_USESHOWWINDOW
                               si.wShowWindow = %SW_Hide
                               si.hStdOutput = hWriteSTDOUTPipe
                               si.hStdError = hWriteSTDOUTPipe
                               si.hStdInput = hReadSTDINPipe
                            
                               'Create the console process with which to communicate
                               CreateProcess("gbconsole.exe", "gbconsole.exe", ByVal 0, ByVal 0, ByVal -1, ByVal 0, ByVal 0, ByVal 0, si, pi)
                            End Sub
                            Last edited by Gary Beene; 13 Jun 2017, 07:56 AM. Reason: Paul's suggested PBWin app tweaks

                            Comment


                            • #34
                              Gary,
                              your windows program talks to the chess engine and gets replies.
                              Your problem will be the console program which I expect you don't need anyway as you replace it with the chess engine.
                              I've just used it to start a game using ETchess.
                              A couple of small changes might be useful:


                              Code:
                                  CASE %IDC_Get
                                      readfile(hReadSTDOUTPipe, BYVAL VARPTR(DataReceived),LEN(DataReceived), num , BYVAL 0)
                                      CONTROL SET TEXT hDlg, %IDC_TextG, DataReceived       '#### you had %IDC_Get so the reply appeared in the button, not the box
                              
                              
                                  CASE %IDC_Send
                                      'DataToSend="gbboard test" + $CRLF
                              
                                      CONTROL GET TEXT hDlg, %IDC_TextS TO DataToSend  '#### instead of a fixed data, send the content of the text box
                              
                                      DataToSend += $CRLF
                              
                                      writefile(hWriteSTDINPipe, BYVAL STRPTR(DataToSend),LEN(DataToSend), num , BYVAL 0)



                              Comment


                              • #35
                                Hi Paul!
                                Thanks for the tweaks!

                                I've just used it to start a game using ETchess.
                                ... you said it worked starting the Chess Engine! And exchanged a few message with it? Great!

                                Since the app pair I posted don't seem to be talking to each other, then the console program I wrote would seem at fault here.

                                A few observations where I can start looking. The CreateProcess line of code does not call up the console app. If I manually call up the console app and type something in, the PBWin version freezes up ("... not responding ..."). Pressing the Get/Send button on the PBWin button doesn't appear to to anything.

                                So as simple/straight forward as I thought the sample console program is, I've apparently gotten it wrong. But I appreciate your feedback on the PBWin app working. I'll go look closer at the console app.
                                Last edited by Gary Beene; 13 Jun 2017, 08:03 AM.

                                Comment


                                • #36
                                  Paul,

                                  And, I'll try my PBWin app out on a chess engine too, to see if it works for me as it did for you.

                                  But I definitely want to know why the console part I wrote is not responding/working as expected.

                                  I thought the console app was so simple, that if the pair of apps wasn't working, then it would be the PBWin at fault, not the other way around! I've written only a handful of console apps ever, so more to learn there.


                                  I updated the code above with your tweaks. Thanks again.

                                  Comment


                                  • #37
                                    Gary,
                                    if you use STDOUT instead of PRINT then your console program works one way and correctly sends messages to your windows program.

                                    I don't have time to look at it at the moment but I remember there was some sort of problem with STDIN and using the ReadFile(?) API solved the problem.
                                    It looks like you might have been thinking about that anyway as you already get the handle to use for ReadFile .. but you then use STDIN instead

                                    Paul.

                                    Comment


                                    • #38
                                      Paul,
                                      Yes, thanks, I do recall the same warnings about using STDIN vs readfile and that did drive the original code to get the handle, But I seem to have lost the thought when I finished up the console app. I'll give it some attention but like you my time today is going to be pulled in a few directions. I hope to get some time to work on it but it's more likely to be later in the day.

                                      At least now with your test results (and code), I can feel like the solution is not far off.

                                      Comment


                                      • #39
                                        if you use STDOUT instead of PRINT then your console program works one way and correctly sends messages to your windows program.
                                        Two things about this post may be misleading..

                                        1. The PB/CC STDOUT statement sends to stdout, wherever that happens to be at the time. Period. Whomever is reading that file (a pipe or mailslot is a file), well, they read it.
                                        2. The PB/CC STDOUT command does NOT send messages "as the term 'message' is generally interpreted when in a programming for Windows)r) environment.

                                        Ditto post #38 ... 'stdin' (as read by the PB/CC STDIN [LINE] Statement is stdin and it's source makes no difference.

                                        In both cases, however, you'd be well advised to check that the PB/CC statements STDOUT and STDIN respect in-process redirection (WinAPI SetStdHandle call). ISTR STDOUT does not; I could be wrong but if you are using in-process redirection of stdout or stdin I'd suggest you explicitly add testing for this.


                                        Just FWIW...

                                        Code:
                                           hStdIn =  GetStdHandle (%STANDARD_INPUT_HANDLE)
                                           hFile   =  FREEFILE
                                           OPEN   HANDLE hstdin FOR INPUT AS hFile
                                           DO
                                             LINE INPUT....
                                           LOOP
                                        That is, the standard handles ARE suitable for use with the PB 'OPEN HANDLE' statement. This might come in handy for someone.

                                        MCM
                                        Michael Mattias
                                        Tal Systems Inc.
                                        Racine WI USA
                                        mmattias@talsystems.com
                                        http://www.talsystems.com

                                        Comment


                                        • #40
                                          Paul,
                                          Could you explain what you did to get my app to talk with et.chess?

                                          This line does seem to start et_chess.exe as a process ...

                                          Code:
                                             CreateProcess("et_chess.exe", "et_chess.exe", ByVal 0, ByVal 0, ByVal -1, ByVal 0, ByVal 0, ByVal 0, si, pi)
                                          But when I try to Get a response from et_chess by sending it a command "xboard", my PBWin app locks up.

                                          Obviously I'm not doing what you have done!

                                          Comment

                                          Working...
                                          X