Page 1 of 1

ReadProgramError() & ReadProgramString() for Unicode

Posted: Thu Sep 02, 2010 8:42 pm
by c4s
Please add unicode support for ReadProgramError() and ReadProgramString().
Especially StdErr is important for me because for the string we can use ReadProgramData() as a workaround but something similar doesn't exist for the error output!

Well there is a complete API way of doing it (starting program, reading, closing etc.) but I don't want to use it anymore because some users said that my application doesn't work since I replaced the PureBasic functions with the API code and I can't find an error because this OpenProcess_(), pipe, access rights, handle stuff is way to hard to understand for me...
Here is the code I'm talking about: http://www.purebasic.fr/english/viewtop ... 13&t=41952


(Adding it in 4.51 final would be nice. :wink:)

Re: ReadProgramError() & ReadProgramString() for Unicode

Posted: Thu Sep 02, 2010 9:05 pm
by Rescator
Um, those two should be unicode.
but that dictates that the other program is also unicode.
If you mix two unicode and ascii programs then one program will receive unicode while it expects ascii and the other will get ascii while it expects unicode.
If a program is x64 then you can be fairly certain that it is also unicode (would be odd to see a x64 ascii program usually), but x86 and you have no idea.

Now, if it's your own programs then you control them and only need to make sure both are unicode (or ascii if supporting old Win9x).

Otherwise you need to identify the other program and if it's unicode or not. Old CLI tools are usually ascii, newer ones vary, the latest should be unicode.

Re: ReadProgramError() & ReadProgramString() for Unicode

Posted: Thu Sep 02, 2010 10:27 pm
by c4s
Yes, I meant that these functions should be safe for interaction between unicode <-> ascii applications. I think I read some time ago that it's planned to add an additional flag in each function for this but I can't remember when and where it was.

My problem here is that there is no workaround for ReadProgramError() like ReadProgramData() for ReadProgramString() and the API-only solution (linked in my first post) doesn't seem to work correctly on some systems.

Re: ReadProgramError() & ReadProgramString() for Unicode

Posted: Thu Sep 02, 2010 10:45 pm
by Rescator
Two compiles of the program then, one unicode and one ascii. (easy to setup with the project compile features in PureBasic).

There also exist a API to check if a window is unicode or not (?!), if the same works with windows cli programs I have no idea.
But if it does then a autocheck could be possible, but don't expect it until the next version or the version after that, it certainly won't make this PB4.51 is in Release Candidate stage (no new features) :P

Re: ReadProgramError() & ReadProgramString() for Unicode

Posted: Thu Sep 02, 2010 11:28 pm
by c4s
If it would be my program than I wouldn't have a problem with it. Why would I run one of my own executables via the program library anyway? ;)

The situation is more like I'm running for example the MS program format.exe out of my unicode program and want to check it's output.
But you are right. Sadly it will take a little longer until it will be implemented and I'm not sure what I should do now. :|

Re: ReadProgramError() & ReadProgramString() for Unicode

Posted: Thu Sep 02, 2010 11:35 pm
by Rescator
Hmm! That's a Windows OS command, so whether it's ascii or unicode depends on the OS version I believe? tried googling that?

Re: ReadProgramError() & ReadProgramString() for Unicode

Posted: Fri Sep 03, 2010 9:10 am
by Fred
c4s wrote:(Adding it in 4.51 final would be nice. :wink:)
FYI, we don't add feature in bugfix only release.

Re: ReadProgramError() & ReadProgramString() for Unicode

Posted: Sun Jul 17, 2011 6:43 pm
by djes
This is not the normal behaviour, and it's a big bug when you have to wait til the end of the called program to get the output! Here's a quick and dirty fix for other cases (unicode compilation only)

Code: Select all

Procedure.s ASCII2UTF8(Str.s)
  ProcedureReturn PeekS(@Str, -1, #PB_Ascii)
EndProcedure  

ProgramNr = RunProgram("help", "", "", #PB_Program_Open | #PB_Program_Read | #PB_Program_Hide)

If ProgramNr
  While ProgramRunning(ProgramNr)
    If AvailableProgramOutput(ProgramNr)
      Output.s + ASCII2UTF8(ReadProgramString(ProgramNr))
      Debug Output  ;; Bug? -> With unicode enabled just one big string
    EndIf
  Wend
  
  CloseProgram(ProgramNr)
EndIf

i = 1
nb = CountString(Output, Chr(13) + Chr(10))
If nb >= 1
  For i = 1 To nb + 1
    ;extract lines and get out CR+LF        
    NewPath.s = StringField(Output, i, Chr(13) + Chr(10))
    NewPath.s = ReplaceString(ReplaceString(NewPath.s, Chr(13), ""), Chr(10), "")
    If NewPath <> ""
      Debug NewPath
    EndIf
  Next i
EndIf


Re: ReadProgramError() & ReadProgramString() for Unicode

Posted: Mon Jul 18, 2011 4:36 pm
by djes
Here's another quickfix based on readprogramdata().

Code: Select all

Global MyReadProgramStringBuffer.s

Procedure.s MyReadProgramString(ProgramNr)
  Size = AvailableProgramOutput(ProgramNr)
  If Size > 0
    Repeat
      ReadProgramData(ProgramNr, @Char.b, 1)
      MyReadProgramStringBuffer + Chr(Char)
    Until Char = $0A Or AvailableProgramOutput(ProgramNr) = 0
    If Char <> $0A
      ProcedureReturn ""
    Else
      Temp.s = MyReadProgramStringBuffer     
      MyReadProgramStringBuffer = ""
      ProcedureReturn ReplaceString(ReplaceString(Temp, Chr(13), ""), Chr(10), "")
    EndIf
  EndIf
EndProcedure

ProgramNr = RunProgram("help", "", "", #PB_Program_Open | #PB_Program_Read | #PB_Program_Hide)

If ProgramNr
  While ProgramRunning(ProgramNr)
    If AvailableProgramOutput(ProgramNr)
      Output.s = MyReadProgramString(ProgramNr)
      Debug Output
    EndIf
  Wend
  CloseProgram(ProgramNr)
EndIf

Another one which works better with some programs

Code: Select all

Global *MyReadProgramStringBuffer = AllocateMemory(1024)

Procedure.s MyReadProgramString(ProgramNr)
  Static MyReadProgramOffset.i = 0
  
  Size = AvailableProgramOutput(ProgramNr)
  If Size > 0
    Repeat
      ReadProgramData(ProgramNr, @Char.b, 1)
      PokeB(*MyReadProgramStringBuffer + MyReadProgramOffset, Char)
      MyReadProgramOffset + 1
    Until Char = $0A Or AvailableProgramOutput(ProgramNr) = 0 Or MyReadProgramOffset > 255
    If Char <> $0A
      ProcedureReturn ""
    Else
      PokeB(*MyReadProgramStringBuffer + MyReadProgramOffset, 0)
      Temp.s = PeekS(*MyReadProgramStringBuffer, -1, #PB_Ascii)
      MyReadProgramOffset = 0
      ProcedureReturn ReplaceString(ReplaceString(Temp, Chr(13), ""), Chr(10), "")
    EndIf
  EndIf
EndProcedure

Compiler = RunProgram("help", "", "", #PB_Program_Open|#PB_Program_Read)
Output$ = ""
If Compiler
  While ProgramRunning(Compiler)
    If AvailableProgramOutput(Compiler)
      Output$ + MyReadProgramString(Compiler) + Chr(13)
    EndIf
  Wend
  Output$ + Chr(13) + Chr(13)
  Output$ + "Exitcode: " + Str(ProgramExitCode(Compiler))
  
  CloseProgram(Compiler) ; Close the connection to the program
EndIf

MessageRequester("Output", Output$)

Re: ReadProgramError() & ReadProgramString() for Unicode

Posted: Mon Jul 18, 2011 6:30 pm
by c4s
@djes
The workaround for ReadProgramString() is known (see first post). The only bad thing is that there is no easy workaround for ReadProgramError()...

Re: ReadProgramError() & ReadProgramString() for Unicode

Posted: Mon Jul 18, 2011 7:34 pm
by djes
Did you tried to redirect the error output to standard input? Like this : http://www.microsoft.com/resources/docu ... x?mfr=true