Handle an external program via stdin/out/error

Share your advanced PureBasic knowledge/code with the community.
User avatar
Kwai chang caine
Always Here
Always Here
Posts: 5342
Joined: Sun Nov 05, 2006 11:42 pm
Location: Lyon - France

Re: Handle an external program via stdin/out/error

Post by Kwai chang caine »

Do you now the codepage which is used normally for french?
Unfortunately not :|
I use the default french options of W10
How can i have this information ? :oops:
Infratec wrote:Marc56us meant that it is Ok.
Yes you have right :shock:
Then... or he looked bad :wink: ....or he enjoyed a little too much of the aperitif :lol:
Because me, i always have this bad characters, even with your last update with "863 Canadian-french and 1252 Latin" :oops:
ImageThe happiness is a road...
Not a destination
infratec
Always Here
Always Here
Posts: 6817
Joined: Sun Sep 07, 2008 12:45 pm
Location: Germany

Re: Handle an external program via stdin/out/error

Post by infratec »

Hm...
then you need to tell me which byte represents è.
Use ShowMemory(*Buffer, ReadLen) to show the received data as bytes in the buffer.
infratec
Always Here
Always Here
Posts: 6817
Joined: Sun Sep 07, 2008 12:45 pm
Location: Germany

Re: Handle an external program via stdin/out/error

Post by infratec »

Open a cmd box and execute chcp and tell me the number.
Last edited by infratec on Mon Nov 25, 2019 10:28 pm, edited 1 time in total.
infratec
Always Here
Always Here
Posts: 6817
Joined: Sun Sep 07, 2008 12:45 pm
Location: Germany

Re: Handle an external program via stdin/out/error

Post by infratec »

Added CP 850.
Marc56us
Addict
Addict
Posts: 1477
Joined: Sat Feb 08, 2014 3:26 pm

Re: Handle an external program via stdin/out/error

Post by Marc56us »

Works fine now (see Last edited by infratec on Mon Nov 25, 2019 10:24 pm)

KCC was right, « à » and « è » were KO before your last version.
I hadn't looked at all the accents (é and ô were OK so I didn't read any further)
Now it's OK

PS. Default code page for french console is 850
In some batch I change it for utf-8 (chcp 65001)

Thanks again infratec
:wink:
User avatar
Kwai chang caine
Always Here
Always Here
Posts: 5342
Joined: Sun Nov 05, 2006 11:42 pm
Location: Lyon - France

Re: Handle an external program via stdin/out/error

Post by Kwai chang caine »

PERFECT !!!!
You are too strong INFRATEC 8)
I was afraid that as usual I'm still the only one to have bad characters :oops:

Your code is really really really important for me
I use it very often for remote several stdin/out executables
Sincerely thanks for this jewel and your precious works 8) 8)

Image
Marc56Us wrote:KCC was right
I thought you were talking about aperitif :mrgreen:
Thanks my friend for your help 8)
ImageThe happiness is a road...
Not a destination
rotacak
User
User
Posts: 77
Joined: Tue Feb 14, 2006 2:00 pm

Re: Handle an external program via stdin/out/error

Post by rotacak »

Nice code, but sadly the code will hang (at this line Error$ = ReadProgramError(*Parameter\ProgramID, StringMode)) in case that executed program will still runing (5+ sec) after prints errors on the start.
If program only runs, print error and quit, then is everything ok.
infratec
Always Here
Always Here
Posts: 6817
Joined: Sun Sep 07, 2008 12:45 pm
Location: Germany

Re: Handle an external program via stdin/out/error

Post by infratec »

If you want that I have a look, provide a working code example which I can use for testing.
rotacak
User
User
Posts: 77
Joined: Tue Feb 14, 2006 2:00 pm

Re: Handle an external program via stdin/out/error

Post by rotacak »

I solved it in different way. Running RunProgram() in a thread and reading the errors there. When it will hang there then is does not matter, main program still runs without hanging.
Axolotl
Enthusiast
Enthusiast
Posts: 435
Joined: Wed Dec 31, 2008 3:36 pm

Re: Handle an external program via stdin/out/error

Post by Axolotl »

Hi infratec,
one stupid question. Sorry in advance. :-)
Is the conversion from cp to unicode only needed for the output, or wouldn't you have to convert the input from unicode to cp as well?

TIA.
Happy Coding and stay healthy.
Happy Holidays to all.
Mostly running PureBasic <latest stable version and current alpha/beta> (x64) on Windows 11 Home
infratec
Always Here
Always Here
Posts: 6817
Joined: Sun Sep 07, 2008 12:45 pm
Location: Germany

Re: Handle an external program via stdin/out/error

Post by infratec »

There are no stupid questions, only stupid answers :mrgreen:

A hard to answer question. I don't have an example for such a case.
In general I would say yes. If the codeset is used for output it is also used for input.
But normally a console program needs key inputs and no character inputs.

If you can tell me an example which I can reproduce, I'll do my best to provide a solution.
infratec
Always Here
Always Here
Posts: 6817
Joined: Sun Sep 07, 2008 12:45 pm
Location: Germany

Re: Handle an external program via stdin/out/error

Post by infratec »

infratec
Always Here
Always Here
Posts: 6817
Joined: Sun Sep 07, 2008 12:45 pm
Location: Germany

Re: Handle an external program via stdin/out/error

Post by infratec »

If you add the following, you can see what codepage is in use (at least if you call a console program)

Code: Select all

If *Parameter\ProgramID
      
      Delay(100)
      
      AttachConsole(ProgramID(*Parameter\ProgramID))
      Debug GetConsoleCP_()
      Debug GetConsoleOutputCP_()
      FreeConsole_()
Axolotl
Enthusiast
Enthusiast
Posts: 435
Joined: Wed Dec 31, 2008 3:36 pm

Re: Handle an external program via stdin/out/error

Post by Axolotl »

Hi infratec,
thanks for your answer.

I am using ROBOCOPY for some backup and sync issues.
(See my post on stoping the execution by Cntrl+C -> viewtopic.php?f=5&t=76416)

Now I figured out that there are directories and files with german äöü in it!
Honestly I havent tried it yet on that files and directories.

Some problems to run your suggested code here: (I use latest PB version on 64bit)

Code: Select all

  Debug "AttachConsole = "+AttachConsole(ProgramID(idProg)) ;' not a function, ... !! 

with

Code: Select all

Import "Kernel32.lib" 
   AttachConsole(dwProgID) 
EndImport 

Result of all three procedures is always 0.

With this code I got: active codepage is 850.

Code: Select all

idProg = RunProgram("cmd", "/c chcp", "", #PB_Program_Open|#PB_Program_Read|#PB_Program_Hide) 
If IsProgram(idProg) 
  While ProgramRunning(idProg) 
    If AvailableProgramOutput(idProg) 
      line$ = ReadProgramString(idProg) 
      If line$ 
        Debug " "+line$  
      EndIf 
    EndIf 
  Wend ;­ program running ... 
  CloseProgram(idProg) 
  Debug "Done "
EndIf

I try to create and test and come back with an working example.

Take care and happy holidays.
Mostly running PureBasic <latest stable version and current alpha/beta> (x64) on Windows 11 Home
Axolotl
Enthusiast
Enthusiast
Posts: 435
Joined: Wed Dec 31, 2008 3:36 pm

Re: Handle an external program via stdin/out/error

Post by Axolotl »

HI again,

with this code it is working as expected...
So from this point of view no conversion for input needed.
Thanks for your time and discussing this with me.

Code: Select all

EnableExplicit 
Global idProg, param$, line$, x 

Global *Buffer, ReadLen 

Procedure.s ExternalProgram_CP850ToUnicode(*Buffer, Length.i)
 
  DataSection
    ExternalProgram_CP850Data:
    Data.u $00c7, $00fc, $00e9, $00e2, $00e4, $00e0, $00e5, $00e7
    Data.u $00ea, $00eb, $00e8, $00ef, $00ee, $00ec, $00c4, $00c5
    Data.u $00c9, $00e6, $00c6, $00f4, $00f6, $00f2, $00fb, $00f9
    Data.u $00ff, $00d6, $00dc, $00f8, $00a3, $00d8, $00d7, $0192
    Data.u $00e1, $00ed, $00f3, $00fa, $00f1, $00d1, $00aa, $00ba
    Data.u $00bf, $00ae, $00ac, $00bd, $00bc, $00a1, $00ab, $00bb
    Data.u $2591, $2592, $2593, $2502, $2524, $00c1, $00c2, $00c0
    Data.u $00a9, $2563, $2551, $2557, $255d, $00a2, $00a5, $2510
    Data.u $2514, $2534, $252c, $251c, $2500, $253c, $00e3, $00c3
    Data.u $255a, $2554, $2569, $2566, $2560, $2550, $256c, $00a4
    Data.u $00f0, $00d0, $00ca, $00cb, $00c8, $0131, $00cd, $00ce
    Data.u $00cf, $2518, $250c, $2588, $2584, $00a6, $00cc, $2580
    Data.u $00d3, $00df, $00d4, $00d2, $00f5, $00d5, $00b5, $00fe
    Data.u $00de, $00da, $00db, $00d9, $00fd, $00dd, $00af, $00b4
    Data.u $00ad, $00b1, $2017, $00be, $00b6, $00a7, $00f7, $00b8
    Data.u $00b0, $00a8, $00b7, $00b9, $00b3, $00b2, $25a0, $00a0
  EndDataSection
 
  Protected Result$, i.i, Byte.a
 
 
  Length - 1
 
  For i = 0 To Length
    Byte = PeekA(*Buffer + i)
    If Byte < $80
      Result$ + Chr(Byte)
    Else
      Result$ + Chr(PeekU(?ExternalProgram_CP850Data + (Byte & $7F) << 1))
    EndIf
  Next i
 
  ProcedureReturn Result$ 
EndProcedure


;' different parameter settings ...  
param$ = "/?"
param$ = "c:\Temp\Source\FolderWithÄÖÜ c:\Temp\Dest\FolderWithÄÖÜ /S "           ;' does the job  
;param$ = "c:\Temp\Source\FolderWithÄÖÜ c:\Temp\Dest\FolderWithÄÖÜ /S /L "        ;' list only, no action on files and folders  
;param$ = "c:\Temp\Source\FolderWithÄÖÜ c:\Temp\Dest\FolderWithÄÖÜ /S /L /quit"   ;' robocopy stops after analysing params 

*Buffer = AllocateMemory(1024, #PB_Memory_NoClear)  
idProg = RunProgram("robocopy.exe", param$, "", #PB_Program_Open|#PB_Program_Read|#PB_Program_Hide) 
If IsProgram(idProg) 
;   Debug "Console Codepage:  "  
;   Debug "AttachConsole = "+AttachConsole(ProgramID(idProg))
;   Debug "GetConsoleCP = "+GetConsoleCP_()
;   Debug "GetConsoleOutputCP = "+GetConsoleOutputCP_()
;   FreeConsole_() 

  Debug "Start Robocopy Help "  
  Repeat       
    While AvailableProgramOutput(idProg)
      ReadLen = AvailableProgramOutput(idProg) 
      If ReadLen > MemorySize(*Buffer)
        *Buffer = ReAllocateMemory(*Buffer, ReadLen, #PB_Memory_NoClear)
      EndIf      
      ReadLen = ReadProgramData(idProg, *Buffer, ReadLen)
      If ReadLen 
        line$ = ExternalProgram_CP850ToUnicode(*Buffer, ReadLen) 
        Debug "  '"+line$+"'" 
      EndIf 
    Wend
    Delay(10)
  Until Not ProgramRunning(idProg)

  CloseProgram(idProg)
  Debug "Done "
EndIf    
FreeMemory(*Buffer)
Mostly running PureBasic <latest stable version and current alpha/beta> (x64) on Windows 11 Home
Post Reply