Results 1 to 21 of 21

Thread: Reading Shell's output in unicode

  1. #1
    Member
    Join Date
    Jan 10
    Posts
    52

    Reading Shell's output in unicode

    Hello,
    There are two great examples how to read Shell's output. However they don't support unicode. Maybe someone could help me adapting them?

    Also, is it possible to cancel running program, like you do in cmd by pressing ctrl+c?
    Last edited by riov; Jul 18th, 2012 at 10:32 AM.

  2. #2
    Frenzied Member Bonnie West's Avatar
    Join Date
    Jun 12
    Location
    InIDE
    Posts
    1,756

    Re: Reading Shell's output in unicode

    Here, try this...

    Please report back if there are any problems.

    Regarding cancelling the shelled program, it's probably possible, although I'm not sure how.
    Last edited by Joacim Andersson; Jul 19th, 2012 at 05:28 AM. Reason: Removed attachement
    On Local Error Resume Next: If Not Empty Is Nothing Then Do While Null: ReDim i(True To False) As Currency: Loop: Else Debug.Assert CCur(CLng(CInt(CBool(False Imp True Xor False Eqv True)))): Stop: On Local Error GoTo 0

    Declare Sub CrashVB Lib "msvbvm60" (Optional DontPassMe As Any)

  3. #3
    Member
    Join Date
    Jan 10
    Posts
    52

    Re: Reading Shell's output in unicode

    Thanks for your time. That's a huge work.
    Sorry, I forgot to mention, that I will use it in Excel. I have tweaked your code a bit. I can now get hWnd value for UserForm, but I don't know how get it for Module, so my example is not working ("Unicode" button). "If TypeOf This Is UserControl Then" is not working in VBA, so I have made a workaround.

    There are two main problems:
    1) I still don't see Unicode characters (they all are changed to "??????")
    2) There is no such a thing as new line, I see "♪◙" instead.

    I saw that you have a reference to vba6 in one place, but newer Office versions use vba7, not sure if that's important.

    P.S. My workbook will only work on 32bit Office version, for it to work on 64bit version it needs API adaptation.
    Attached Files Attached Files

  4. #4
    Frenzied Member Bonnie West's Avatar
    Join Date
    Jun 12
    Location
    InIDE
    Posts
    1,756

    Re: Reading Shell's output in unicode

    Oh, I didn't know you were going to use it in Excel. In that case, the Self-Callback routines may not work.

    Have you tried checking the button through the IsWindowUnicode() function? That may be the reason you couldn't see Unicode characters.

    I reorganized that code in VB6; I haven't tested it in either VBA6 or VBA7.

    EDIT:

    I re-attached the demo project in case someone's still interested.

    To the Moderators:

    Sorry about the exe, but I had the same reason as riov.
    Attached Files Attached Files
    Last edited by Bonnie West; Jul 19th, 2012 at 06:23 AM. Reason: Stripped the offending exe from the zip file
    On Local Error Resume Next: If Not Empty Is Nothing Then Do While Null: ReDim i(True To False) As Currency: Loop: Else Debug.Assert CCur(CLng(CInt(CBool(False Imp True Xor False Eqv True)))): Stop: On Local Error GoTo 0

    Declare Sub CrashVB Lib "msvbvm60" (Optional DontPassMe As Any)

  5. #5
    Super Moderator Joacim Andersson's Avatar
    Join Date
    Jan 99
    Location
    Sweden
    Posts
    13,533

    Re: Reading Shell's output in unicode

    I have removed the attachment since it contained an exe file which is against our rules. Feel free to upload it again without the exe file.
    Joacim Andersson
    If anyone's answer has helped you, please show your appreciation by rating that answer.
    I'd rather run ScriptBrix...
    Joacim's view on stuff.

    MVP

  6. #6
    Member
    Join Date
    Jan 10
    Posts
    52

    Re: Reading Shell's output in unicode

    Controls in UserForm are not able to display Unicode characters by default. For this reason I pass STDOUT & STDERR values to cell. I also use MsgBoxW to display Unicode characters.

    Can you open my worksheet and see the modifications I have made, or should I copy/paste the code somewhere?

    Quote Originally Posted by Joacim Andersson View Post
    I have removed the attachment since it contained an exe file which is against our rules. Feel free to upload it again without the exe file.
    But the same exe is here.
    Last edited by riov; Jul 19th, 2012 at 05:38 AM.

  7. #7
    Super Moderator Joacim Andersson's Avatar
    Join Date
    Jan 99
    Location
    Sweden
    Posts
    13,533

    Re: Reading Shell's output in unicode

    Quote Originally Posted by riov View Post
    But the same exe is here.
    Thanks for letting me know. I'm not a moderator for that forum so I have asked for this to be removed.
    Joacim Andersson
    If anyone's answer has helped you, please show your appreciation by rating that answer.
    I'd rather run ScriptBrix...
    Joacim's view on stuff.

    MVP

  8. #8
    Super Moderator Hack's Avatar
    Join Date
    Aug 01
    Location
    Searching for mendhak
    Posts
    58,292

    Re: Reading Shell's output in unicode

    Quote Originally Posted by riov View Post
    Sorry, I forgot to mention, that I will use it in Excel.
    Excel VBA thread moved to Office Development
    Quote Originally Posted by riov View Post
    But the same exe is here.
    Not anymore. Thanks for letting us know.
    Please use [Code]your code goes in here[/Code] tags when posting code.
    When you have received an answer to your question, please mark it as resolved using the Thread Tools menu.
    Before posting your question, did you look here?
    Got a question on Linux? Visit our Linux sister site.
    I dont answer coding questions via PM or EMail. Please post a thread in the appropriate forum section.

    Creating A Wizard In VB.NET
    Paging A Recordset
    What is wrong with using On Error Resume Next
    Good Article: Language Enhancements In Visual Basic 2010
    Upgrading VB6 Code To VB.NET
    Microsoft MVP 2005/2006/2007/2008/2009/2010/2011/2012/Defrocked

  9. #9
    Member
    Join Date
    Jan 10
    Posts
    52

    Re: Reading Shell's output in unicode

    Quote Originally Posted by Bonnie West View Post
    Oh, I didn't know you were going to use it in Excel. In that case, the Self-Callback routines may not work.
    You can try your code by creating folder with a name:
    Code:
    ChrW$(&H6C49) & ChrW$(&H8BED) & ChrW$(&H6F22) & ChrW$(&H8A9E) & "-" & ChrW$(&H439) & ChrW$(&H446) & ChrW$(&H443) & ChrW$(&H43A) & ChrW$(&H435) & ChrW$(&H43D) & "-" & ChrW$(&H3C0) & ChrW$(&H3C1) & ChrW$(&H3C3)
    and then using:
    Code:
    txtPrompt = "cmd /c & dir"
    In windows this folder will look like:

    In CMD:

    But your application will show:
    ????-??????-???
    Last edited by riov; Jul 19th, 2012 at 02:02 PM.

  10. #10
    Super Moderator koolsid's Avatar
    Join Date
    Feb 05
    Location
    Mumbai, India
    Posts
    11,449

    Re: Reading Shell's output in unicode

    Excel worksheets cannot show unicode characters like that. Here is one way to work with unicode characters in Excel.

    Change the font in Say Cell F14 to "Arial Unicode MS"

    Now create a new module and paste this code.

    Code:
    Sub sample()
        Range("F14").Value = Unicode(&H6C49)
    End Sub
    
    Function Unicode(val As Long)
       Unicode = ChrW(val)
    End Function
    Now Run the Sub Sample. Do you now see the unicode characters in Cell F4? See snapshot
    Attached Images Attached Images  
    A good exercise for the Heart is to bend down and help another up...
    Please Mark your Thread "Resolved", if the query is solved

    Microsoft MVP: 2011 - Till Date IMP Links : Acceptable Use Policy, FAQ

    MyGear:
    Sony VGN-FZ27G with a triple boot between (XP+Office 2003+VB6), (VISTA+Office 2007+VS2008) and (Win7+Office 2010+VS2010) || Sony VPCCB-45FN with a Win7+Office 2010+VS2010. VM: (XP+Office 2003+VB6), (VISTA+Office 2007+VS2008), (Win8+Office 2010+VS2012) || Mac Book Pro (10.6.8) with Office 2011

  11. #11
    Frenzied Member Bonnie West's Avatar
    Join Date
    Jun 12
    Location
    InIDE
    Posts
    1,756

    Re: Reading Shell's output in unicode

    Try hard-coding the path in the line:

    Code:
    myConsole.RunCommand hWnd, App.Path & "\" & sUnicodeFolder & "\test.exe"
    sUnicodeFolder is the folder name you gave. It should now be able to run the console app. The reason the VB TextBox corrupts the commandline is because it can't handle Unicode strings. You'll probably have to find an alternative to VB controls that can handle Unicode properly before you can pass Unicode strings to the RunCommand method.

    In the ReadPipe routine, you may want to use the Left$(StrConv(..)) code instead of the OemToCharBuff to properly read the incoming data.
    On Local Error Resume Next: If Not Empty Is Nothing Then Do While Null: ReDim i(True To False) As Currency: Loop: Else Debug.Assert CCur(CLng(CInt(CBool(False Imp True Xor False Eqv True)))): Stop: On Local Error GoTo 0

    Declare Sub CrashVB Lib "msvbvm60" (Optional DontPassMe As Any)

  12. #12
    Member
    Join Date
    Jan 10
    Posts
    52

    Re: Reading Shell's output in unicode

    Quote Originally Posted by koolsid View Post
    (...) Here is one way to work with unicode characters in Excel.
    Change the font in Say Cell F14 to "Arial Unicode MS"
    There is no need to change to that font, Calibri works as well:

  13. #13
    Super Moderator koolsid's Avatar
    Join Date
    Feb 05
    Location
    Mumbai, India
    Posts
    11,449

    Re: Reading Shell's output in unicode

    Yup you are right. Strange it didn't earlier but now when tested it with Calibri, it works just fine.
    A good exercise for the Heart is to bend down and help another up...
    Please Mark your Thread "Resolved", if the query is solved

    Microsoft MVP: 2011 - Till Date IMP Links : Acceptable Use Policy, FAQ

    MyGear:
    Sony VGN-FZ27G with a triple boot between (XP+Office 2003+VB6), (VISTA+Office 2007+VS2008) and (Win7+Office 2010+VS2010) || Sony VPCCB-45FN with a Win7+Office 2010+VS2010. VM: (XP+Office 2003+VB6), (VISTA+Office 2007+VS2008), (Win8+Office 2010+VS2012) || Mac Book Pro (10.6.8) with Office 2011

  14. #14
    Member
    Join Date
    Jan 10
    Posts
    52

    Re: Reading Shell's output in unicode

    Quote Originally Posted by Bonnie West View Post
    In the ReadPipe routine, you may want to use the Left$(StrConv(..)) code instead of the OemToCharBuff to properly read the incoming data.
    How exactly to change this line?
    Code:
    Call OemToCharBuff(baOutput(0), StrPtr(sBuffer), lBytesRead)
    I have done the following:
    Code:
    sUnicode = ChrW$(&H6C49) & ChrW$(&H8BED) & ChrW$(&H6F22) & ChrW$(&H8A9E) & "-" & ChrW$(&H439) & ChrW$(&H446) & ChrW$(&H443) & ChrW$(&H43A) & ChrW$(&H435) & ChrW$(&H43D) & "-" & ChrW$(&H3C0) & ChrW$(&H3C1) & ChrW$(&H3C3)
    txtPrompt = "cmd /c cd C:\" & sUnicode & " & dir"
    And the result is this:

    1. Command is working
    2. TextBox can display unicode (see 3);
    3. Output is still not in unicode (see 1), I have also tried to write output to a cell & txt file - same result;
    4. New line is not working (see 2).
    Last edited by riov; Jul 19th, 2012 at 05:04 PM.

  15. #15
    Frenzied Member Bonnie West's Avatar
    Join Date
    Jun 12
    Location
    InIDE
    Posts
    1,756

    Re: Reading Shell's output in unicode

    In Joacim's original code, he had the option of performing no conversion from OEM characters, as shown below:

    Code:
    sBuffer = Left$(StrConv(baOutput(), vbUnicode), lBytesRead)
    Even in the real command prompt (cmd.exe), Unicode characters aren't displayed properly, even though you can CD into them. Unfortunately, I don't know how to go around that display limitation...
    On Local Error Resume Next: If Not Empty Is Nothing Then Do While Null: ReDim i(True To False) As Currency: Loop: Else Debug.Assert CCur(CLng(CInt(CBool(False Imp True Xor False Eqv True)))): Stop: On Local Error GoTo 0

    Declare Sub CrashVB Lib "msvbvm60" (Optional DontPassMe As Any)

  16. #16
    Member
    Join Date
    Jan 10
    Posts
    52

    Re: Reading Shell's output in unicode

    Quote Originally Posted by Bonnie West View Post
    Code:
    sBuffer = Left$(StrConv(baOutput(), vbUnicode), lBytesRead)
    This has solved issue with new line, now it is displayed correctly.

    Quote Originally Posted by Bonnie West View Post
    Even in the real command prompt (cmd.exe), Unicode characters aren't displayed properly, even though you can CD into them. Unfortunately, I don't know how to go around that display limitation...
    Yes, some (not all) unicode characters in cmd are not displayed, but only because of font issue (good discussion about this here). As Philipp says "It has nothing to do with encodings since the Windows console always uses Unicode internally. The characters are simply not available in the fonts you use...". So theoretically it should be possible to read unicode characters or at least it should be possible to read those that are displayed (e.g., Russian, Greek etc.).

    One interesting observation: if I use cmd /u /c your code stops displaying output, STDOUT = "" (I have tried to output it to TextBox, cell, MsgBox), but Debug.Print displays it (that's the first time I see such behavior). What is the most interesting here, that in Immediate window I see not ??? where unicode characters supposed to be, but some other strange characters, it is like STDOUT contains unicode output, but I cannot visualize it anywhere, bizarre.
    Last edited by riov; Jul 20th, 2012 at 02:21 AM.

  17. #17
    Member
    Join Date
    Jan 10
    Posts
    52

    Re: Reading Shell's output in unicode

    I am doing some experiments. Maybe anyone can tell me how to convert non null-terminated byte array to Unicode string?

    Not sure if my terminology is right, but here is what I have and what I need:
    1.1. Text:
    Code:
    C:\ABCD-汉语漢語-йцукен-πρσ
    1.2. String:
    Code:
    "C:\ABCD-" & ChrW$(&H6C49) & ChrW$(&H8BED) & ChrW$(&H6F22) & ChrW$(&H8A9E) & "-" & ChrW$(&H439) & ChrW$(&H446) & ChrW$(&H443) & ChrW$(&H43A) & ChrW$(&H435) & ChrW$(&H43D) & "-" & ChrW$(&H3C0) & ChrW$(&H3C1) & ChrW$(&H3C3)
    1.3. Array of Bytes (2 bytes, UTF16):
    Code:
    067 000 058 000 092 000 065 000 066 000 067 000 068 000 045 000 073 108 237 139 034 111 158 138 045 000 057 004 070 004 067 004 058 004 053 004 061 004 045 000 192 003 193 003 195 003 013 000
    -------------------------------------------------------------------------------------------------------------------

    2.1*. Text (supposed to be the same as in 1.1):
    Code:
    C:\ABCD-걉čΖ*ęΌ’čŖ˛-ŠΉŃ†ŃƒŠŗŠ΅Š½-Ļ€ĻĻƒ
    2.2*. Array of Bytes (maybe UFT8):
    Code:
    067 058 092 065 066 067 068 045 230 177 137 232 175 173 230 188 162 232 170 158 045 208 185 209 134 209 131 208 186 208 181 208 189 045 207 128 207 129 207 131
    I need a solution to get from (2.2) to (1.1).
    Notice that Latin characters in (2.2) are encoded by 1 byte, and non-Latin by 2 bytes.

  18. #18
    Member
    Join Date
    Jan 10
    Posts
    52

    Re: Reading Shell's output in unicode

    So, nobody can solve this?

  19. #19
    Super Moderator Joacim Andersson's Avatar
    Join Date
    Jan 99
    Location
    Sweden
    Posts
    13,533

    Re: Reading Shell's output in unicode

    I'm not 100% sure I understand your question but I think you want to be able to read a UTF-8 string in to a regular Unicode string (UTF-16).

    The only way that I can think of to do this with VB6 is to use an ADODB.Stream object. Set a reference to Microsoft ActiveX Data Objects Library and use code similar to this:
    Code:
    Public Function Utf8ToString(data() As Byte) As String
      Dim adoStream As ADODB.Stream
    
      Set adoStream = New ADODB.Stream
      adoStream.Charset = "utf-8"
      adoStream.Mode = adModeReadWrite
      adoStream.Type = adTypeBinary
      adoStream.Open
      adoStream.Write data
      adoStream.Flush
      adoStream.Position = 0
      adoStream.Type = adTypeText
      Utf8ToString = adoStream.ReadText
      adoStream.Close
    End Function
    Joacim Andersson
    If anyone's answer has helped you, please show your appreciation by rating that answer.
    I'd rather run ScriptBrix...
    Joacim's view on stuff.

    MVP

  20. #20
    Member
    Join Date
    Jan 10
    Posts
    52

    Re: Reading Shell's output in unicode

    Thanks. It helped.

  21. #21
    Member
    Join Date
    Jan 10
    Posts
    52

    Re: Reading Shell's output in unicode

    After doing some testing, I have found one major problem with this code.
    If my command is something like cmd /c echo test & program.exe this code becomes from asynchronous to synchronous. By this I mean that program hangs if program.exe is executed for let's say 1 hour. Scenario: when PeekNamedPipe checks if there is anything to read it find that echo test has outputted text, but it does not know that program.exe will be executed for 1 hour, that's where program hangs as it tries to read output with ReadFile. I think the only solution here is to use ReadFileEx instead. It could be used in a Loop by checking for WAIT_IO_COMPLETION. Problem is that I cannot find any good examples how to use this API. Maybe anyone could advice?

    Update: What complicates a situation is that CreateProcess does not start program.exe, it's only started with ReadFile.
    Last edited by riov; Aug 2nd, 2012 at 02:41 PM.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •