ReadProgramString() not working with unicode exe?

Everything else that doesn't fall into one of the other PB categories.
User avatar
Kukulkan
Addict
Addict
Posts: 1422
Joined: Mon Jun 06, 2005 2:35 pm
Location: germany
Contact:

ReadProgramString() not working with unicode exe?

Post by Kukulkan »

Hi,

I try to get the result of a nslookup call using purebasic RunProgram() function. Here is how I do:

Code: Select all

#LineBreak = #CRLF$

; run an executable and return his console output
Procedure.s runCmd(program.s, params.s, wd.s = "", lf.s = #LineBreak, Hidden.b = #False)
  Protected Compiler.i
  If Hidden.b = #True
    Compiler.i = RunProgram(program.s, params.s, wd.s, #PB_Program_Open|#PB_Program_Read|#PB_Program_Hide)
  Else
    Compiler.i = RunProgram(program.s, params.s, wd.s, #PB_Program_Open|#PB_Program_Read)
  EndIf
  Protected Output.s = ""
  If Compiler.i
    While ProgramRunning(Compiler.i)
      If AvailableProgramOutput(Compiler.i)
        Protected Line.s = ReadProgramString(Compiler.i)
        Output.s + Line.s + lf.s
      EndIf
    Wend
    CloseProgram(Compiler.i) ; Close the connection to the program
  EndIf
  ProcedureReturn Output.s
EndProcedure

Debug runCmd("nslookup", "-q=MX google.com.")
Sadly, using Unicode does not work at all. Is this a bug?

Got it to work like this, but is this really needed?

Code: Select all

; run an executable and return his console output
Procedure.s runCmd(program.s, params.s, wd.s = "", lf.s = #LineBreak, Hidden.b = #False)
  Protected Compiler.i
  If Hidden.b = #True
    Compiler.i = RunProgram(program.s, params.s, wd.s, #PB_Program_Open|#PB_Program_Read|#PB_Program_Hide)
  Else
    Compiler.i = RunProgram(program.s, params.s, wd.s, #PB_Program_Open|#PB_Program_Read)
  EndIf
  Protected Output.s = ""
  If Compiler.i
    While ProgramRunning(Compiler.i)
      Protected LineLength.i = AvailableProgramOutput(Compiler.i)
      If LineLength.i > 0
        Protected *buffer = AllocateMemory(LineLength.i)
        ReadProgramData(Compiler.i, *buffer, LineLength.i)
        Protected Line.s = PeekS(*buffer, LineLength.i, #PB_Ascii)
        FreeMemory(*buffer)
        Output.s + Line.s + lf.s
      EndIf
    Wend
    CloseProgram(Compiler.i) ; Close the connection to the program
  EndIf
  ProcedureReturn Output.s
EndProcedure
Kukulkan
c4s
Addict
Addict
Posts: 1981
Joined: Thu Nov 01, 2007 5:37 pm
Location: Germany

Re: ReadProgramString() not working with unicode exe?

Post by c4s »

This feature request might be related: ReadProgramString() and ReadProgramError() with unicode
If any of you native English speakers have any suggestions for the above text, please let me know (via PM). Thanks!
User avatar
Kukulkan
Addict
Addict
Posts: 1422
Joined: Mon Jun 06, 2005 2:35 pm
Location: germany
Contact:

Re: ReadProgramString() not working with unicode exe?

Post by Kukulkan »

Yes, this seems to be the same issue. In April 2010 freak stated it will be changed in the future. It is not until now :(

By the way, the somewhat complicated aproach by c4s is not needed (see my first post with second code as solution).

Kukulkan
c4s
Addict
Addict
Posts: 1981
Joined: Thu Nov 01, 2007 5:37 pm
Location: Germany

Re: ReadProgramString() not working with unicode exe?

Post by c4s »

Kukulkan wrote:By the way, the somewhat complicated aproach by c4s is not needed (see my first post with second code as solution).
Really? I didn't test it yet, but does your workaround also work for ReadProgramError() or just ReadProgramString() as I've mentioned in that thread?
If any of you native English speakers have any suggestions for the above text, please let me know (via PM). Thanks!
User avatar
Kukulkan
Addict
Addict
Posts: 1422
Joined: Mon Jun 06, 2005 2:35 pm
Location: germany
Contact:

Re: ReadProgramString() not working with unicode exe?

Post by Kukulkan »

Hi c4s,

sorry, I did noch check all of your functionality. The ReadProgramError() function was not needed by myself. Maybe the effort is needed only there?

Best,

Kukulkan
gnozal
PureBasic Expert
PureBasic Expert
Posts: 4229
Joined: Sat Apr 26, 2003 8:27 am
Location: Strasbourg / France
Contact:

Re: ReadProgramString() not working with unicode exe?

Post by gnozal »

I use this workaround (found on this forum ?) [example on WinXP x86 (french) with ping.exe] :

Code: Select all

Procedure.s ReadProgramStringSafe(ProgramNr) ; ReadProgramString does NOT support Unicode
  ;
  Protected Char.a, ReturnValue.s
  ;
  Static MyReadProgramOffset = 0
  ;
  Shared *MyReadProgramStringBuffer
  ;
  Size = AvailableProgramOutput(ProgramNr)
  If Size > 0
    ;
    Repeat
      ;
      ReadProgramData(ProgramNr, @Char, 1)
      PokeB(*MyReadProgramStringBuffer + MyReadProgramOffset, Char)
      MyReadProgramOffset + 1
      ;
      If AvailableProgramOutput(ProgramNr) = 0 Or MyReadProgramOffset > 255
        Break
      EndIf
      ;
    Until Char = $0A
    ;
    If Char <> $0A
      ReturnValue = ""
    Else
      PokeB(*MyReadProgramStringBuffer + MyReadProgramOffset, 0)
      ReturnValue = PeekS(*MyReadProgramStringBuffer, -1, #PB_Ascii)
      MyReadProgramOffset = 0
      ReturnValue = ReplaceString(ReturnValue, Chr(13), "")
      ReturnValue = ReplaceString(ReturnValue, Chr(10), "")
    EndIf
    ;
  EndIf
  ;
  ProcedureReturn ReturnValue
  ;
EndProcedure
Procedure IsRemotePCAvailable(RemotePC.s)
  ;
  Protected ConnectionOk, ResponseLine, Prog, FindLast, FindFirst, TimeOut.i
  ;
  Shared IsRemotePCAvailable_IP.s
  Shared *MyReadProgramStringBuffer
  ;
  IsRemotePCAvailable_IP = ""
  ;
  *MyReadProgramStringBuffer = AllocateMemory(2048)
  If *MyReadProgramStringBuffer
    ;
    Prog = RunProgram("ping.exe", RemotePC, GetTemporaryDirectory(), #PB_Program_Open | #PB_Program_Read | #PB_Program_Hide)
    If Prog
      TimeOut = ElapsedMilliseconds() + 5000
      Debug "IsRemotePCAvailable : START -> " + RemotePC
      While ProgramRunning(Prog)
        Response$ = ReadProgramStringSafe(Prog)
        If Response$
          Debug "---> " + Response$
          ResponseLine + 1
          If ResponseLine = 1
            IsRemotePCAvailable_IP = RemotePC
            FindFirst = FindString(Response$, "[", 1)
            If FindFirst
              FindLast = FindString(Response$, "]", FindFirst + 1)
              If FindLast
                IsRemotePCAvailable_IP = Mid(Response$, FindFirst + 1, FindLast - FindFirst - 1)
              EndIf
            EndIf
          ElseIf ResponseLine = 2
            If FindString(Response$, "TTL", 1)
              ConnectionOk = #True
            Else
              IsRemotePCAvailable_IP = ""
            EndIf
            KillProgram(Prog)
            Break
          EndIf
        EndIf
        If ElapsedMilliseconds() > TimeOut
          KillProgram(Prog)
          Break
        EndIf
      Wend
      If ResponseLine = 1
        IsRemotePCAvailable_IP = ""
      EndIf
      CloseProgram(Prog)
      Debug "IsRemotePCAvailable : END"
    Else
      ConnectionOk = -1
    EndIf
    ;
    FreeMemory(*MyReadProgramStringBuffer)
    ;
  Else
    ConnectionOk = -1
  EndIf
  ;
  ProcedureReturn ConnectionOk
  ;
EndProcedure

Debug IsRemotePCAvailable("z1501")
For free libraries and tools, visit my web site (also home of jaPBe V3 and PureFORM).
Post Reply