For a larger vba application I need to use powershell scripts to give me the filenames on a share. As I live in Germany, these filenames contain a lot of german special characters like ü, ä, and so on.
The output of the powershell script, that should (and on the PS Console does) display those characters correctly is not displayed correctly in VBA. I've made up this minimal example to demonstrate this.
Any solution that gives back für instead of fr is appreciated.
Option Explicit
Const HK = """"
Sub ScanDrive()
Dim s As String, command As String
command = "echo 'für'"
Debug.Print (command)
'Method1: start PS in CMD with /u parameter
s = CreateObject("Wscript.Shell").exec("cmd /u /c powershell.exe -command " & HK & command & HK).StdOut.ReadAll
Debug.Print (s)
'Method2: start PS directly (preferred)
s = CreateObject("Wscript.Shell").exec("powershell.exe -command " & HK & command & HK).StdOut.ReadAll
Debug.Print (s)
End Sub
My output looks like this (though vba doesn't display the `````` character at all):
echo 'für'
fr
fr
I've already learned that I can change the PS output encoding when I'm writing to a file-output. Unfortunately this will not be an option.
In my understanding I'd have to make Excel read UTF-8 (I guess, that's what it is) or make the PS Console write out Win-1252 (also just a guess, that this is, what Excel uses).
As I have to deploy this script in a company I cannot rely on any global switches for the PS Console.
Update
According to JosefZ 's comment I put the command as [System.Console]::OutputEncoding
and got the following in VBA:
IsSingleByte : True
BodyName : ibm850
EncodingName : Westeurop„isch (DOS)
HeaderName : ibm850
WebName : ibm850
WindowsCodePage : 1252
IsBrowserDisplay : False
IsBrowserSave : False
IsMailNewsDisplay : False
IsMailNewsSave : False
EncoderFallback : System.Text.InternalEncoderBestFitFallback
DecoderFallback : System.Text.InternalDecoderBestFitFallback
IsReadOnly : True
CodePage : 850
as opposed to running it directly in the powershell where it states:
IsSingleByte : True
BodyName : iso-8859-1
EncodingName : Westeuropäisch (Windows)
HeaderName : Windows-1252
WebName : Windows-1252
WindowsCodePage : 1252
IsBrowserDisplay : True
IsBrowserSave : True
IsMailNewsDisplay : True
IsMailNewsSave : True
EncoderFallback : System.Text.InternalEncoderBestFitFallback
DecoderFallback : System.Text.InternalDecoderBestFitFallback
IsReadOnly : True
CodePage : 1252
The CreateObject("Wscript.Shell")
seems to work on Dos encoding and CP850.
Luckily, I found the solution.
JosefZ's comment put me on the right track and led me to this underrated answer from Garric to another question.
Adapted his solution to my original minimal example code gives this:
Option Explicit
Const HK = """"
Sub ScanDrive()
Dim s As String, command As String
Dim codepage As String
codepage = "windows-1252"
command = "$OutputEncoding = [Console]::outputEncoding = [System.Text.Encoding]::GetEncoding('" + codepage + "'); echo 'für'"
Debug.Print (command)
s = CreateObject("Wscript.Shell").Exec("powershell.exe -command " & HK & command & HK).StdOut.ReadAll
Debug.Print (s)
End Sub
Et Voilá - We have our german Umlauts correctly :)