Page 1 sur 1

[R] Encodage, console et mode OEM

Posté : ven. 27 déc. 2019 09:57
par DimVar
Bonjour,

Sur ce simple script, comment puis je recuperer la sortie de la commande "DIR" avec les caracteres speciaux liés à la langue FR ?
#include <AutoItConstants.au3>
$run = Run(@ComSpec & " /c " & 'dir c:', "", @SW_HIDE,$STDOUT_CHILD)
ProcessWaitClose($run)
$output = StdoutRead ($run)
ConsoleWrite($run & @CRLF & @CRLF & $output)
Exemple de resultat obtenu :
15/10/2019  12:54               300 temp2.au3
14/10/2019  14:09             5ÿ452 temp3.au3
09/09/2011  02:53             6ÿ769 Web.au3
               6 fichier(s)          112ÿ873 octets
               2 R‚p(s)  65ÿ653ÿ837ÿ824 octets libres
Merci.

Re: [..] Encodage ?

Posté : ven. 27 déc. 2019 10:18
par Tlem
Bonjour Dimvar.
Il me semble bien que cette question à déjà sa réponse sur le forum.

Re: [..] Encodage ?

Posté : ven. 27 déc. 2019 14:25
par DimVar
Plus d'une fois même ! Je m'y suis même intéressé avant de poser la question. Cependant, c’est un sujet que j'ai toujours eu du mal à appréhender (ces questions d'encodage en informatique). Bref.
Mon analyse :
J'ai reproduit l'action dans une CMD =>"Dir c:"
J'ai copié le resultat dans le presse papier, collé dans Notepad++ et
Image
J'en suis là. Je sais que la commande MSDOS envoi du UTF8.
J'ai bon chef ?

Re: [..] Encodage ?

Posté : ven. 27 déc. 2019 14:58
par DimVar
Analyse, épisode 2 :

Bon ! Apres qq sebsauvage et autre bellamy,
ascii = origine de tout apres le big bang
UTF8 = Ascii + unicode si besoin.

Quand je colle le resultat dans notepad++, celui ci me dit que c'est de l'UTF8. Parce que il ouvre tous ses documents par defaut en utf8 ? Ou parce que ce que je colle est vraiment de l'UTF8 ?
J'ai aperçu un topic qui parlait de ConsoleWrite et parametrage de scite pour l'encodage... Je vais creuser cette piste.

Re: [..] Encodage ?  

Posté : ven. 27 déc. 2019 15:06
par jchd
Pas du tout, sauf si le jeu de caractères a été changé avec la commande CHCP 65001.
Par défaut, une console utilise le jeu OEM.

Code : Tout sélectionner

Func _OEMtoString($sCP, $iCodepage = Default)
	If $iCodepage = Default Then $iCodepage = Int(RegRead("HKLM\SYSTEM\CurrentControlSet\Control\Nls\Codepage", "OEMCP"))
	Local $tText = DllStructCreate("byte[" & StringLen($sCP) & "]")
	DllStructSetData($tText, 1, $sCP)
	Local $aResult = DllCall("kernel32.dll", "int", "MultiByteToWideChar", "uint", $iCodepage, "dword", 0, "struct*", $tText, "int", StringLen($sCP), _
			"ptr", 0, "int", 0)
	Local $tWstr = DllStructCreate("wchar[" & $aResult[0] & "]")
	$aResult = DllCall("kernel32.dll", "int", "MultiByteToWideChar", "uint", $iCodepage, "dword", 0, "struct*", $tText, "int", StringLen($sCP), _
			"struct*", $tWstr, "int", $aResult[0])
	Return DllStructGetData($tWstr, 1)
EndFunc   ;==>_OEMtoString

Re: [..] Encodage, console et mode OEM

Posté : lun. 30 déc. 2019 11:42
par DimVar
Merci JCHD. Je ne connaissais pas ces notions de codepage dans la console Windows.

(je passe tout ca par écrit, ca m'aide à retenir)
Le mode console de Windows est paramétré en France sur 850 (voir ci-dessous).
On retrouve le codepage (ou page de code en FR) avec la commande : "mode", dont voici le résultat.
Image

Si on fait un bête "DIR" sous la console et que l'on copie-colle le résultat sous Windows (dans notepad par ex), on obtient des caractères non pris en charge et mal "transformé".
Si l'on recupere le STDREAD d'une commande DOS, on obtient des caractères non pris en charge et mal "transformé".

On peut utiliser la fonction fournie par JCHD plus haut, pour "remettre au propre" tout ça.

Re: [R] Encodage, console et mode OEM

Posté : lun. 30 déc. 2019 13:49
par DimVar
Et pour aller plus loin :
viewtopic.php?f=11&t=5523&p=33722&hilit=codepage#p33722
(Merci aux participants de ce topic)

Re: [..] Encodage, console et mode OEM

Posté : lun. 30 déc. 2019 13:58
par Tlem
DimVar a écrit : lun. 30 déc. 2019 11:42 Si on fait un bête "DIR" sous la console et que l'on copie-colle le résultat sous Windows (dans notepad par ex), on obtient des caractères non pris en charge et mal "transformé".
Pour infos, sur mon PC qui est sous Windows 10x64 Pro, je n'ai pas ce comportement. Un Copié/Collé d'une console DOS me transfert bien les caractères accentués dans le Notepad de Windows. ^^

Edit : Je viens de faire la manip sur une VM en Windows 7 et pareil, les caractères accentués sont bien là. :P

Re: [R] Encodage, console et mode OEM

Posté : lun. 30 déc. 2019 14:04
par jpascal
Si cela peut aider, je me suis créé un petit UDF Convert.au3

La fonction _ConvertTest() sert à trouver le bon convertisseur pour le résultat escompté.
#include-once
#include <StringConstants.au3>

Func _AnsiToOEM($sAnsi)
   Local $a_OEMFName = DllCall('user32.dll', 'Int', 'CharToOem', 'str', $sAnsi, 'str', '')
   If @error = 0 Then Return $a_OEMFName[2]
EndFunc   ;==>_AnsiToOEM

Func _OEMToAnsi($sOEM)
   Local $a_AnsiFName = DllCall('user32.dll', 'Int', 'OemToChar', 'str', $sOEM, 'str', '')
   If @error = 0 Then
      Return $a_AnsiFName[2]
   Else
      Return $sOEM
   EndIf
EndFunc   ;==>_OEMToAnsi

Func _UnicodeToANSI($sUnicode)
   Return BinaryToString(StringToBinary($sUnicode, $SB_UTF8), $SB_ANSI)
EndFunc   ;==>_UnicodeToANSI

Func _AnsiToUnicode($sAnsi)
   Return BinaryToString(StringToBinary($sAnsi, $SB_ANSI), $SB_UTF8)
EndFunc   ;==>_AnsiToUnicode

Func _ConvertTest($sTxt)
   ConsoleWrite('_AnsiToOEM() : ' & _AnsiToOEM($sTxt))
   ConsoleWrite(@CRLF)
   ConsoleWrite('_OEMToAnsi() : ' & _OEMToAnsi($sTxt))
   ConsoleWrite(@CRLF)
   ConsoleWrite('_AnsiToUnicode() : ' & _AnsiToUnicode($sTxt))
   ConsoleWrite(@CRLF)
   ConsoleWrite('_UnicodeToANSI() : ' & _UnicodeToANSI($sTxt))
   ConsoleWrite(@CRLF & @CRLF)
EndFunc   ;==>_TestConversion

Re: [R] Encodage, console et mode OEM

Posté : lun. 30 déc. 2019 14:44
par Tlem
Cela était déjà indiqué ici : viewtopic.php?f=21&t=4108&p=29397&hilit=AnsiToOEM ^^

Re: [R] Encodage, console et mode OEM

Posté : lun. 30 déc. 2019 15:51
par jpascal
Voilà. Rendons à César... :-)

Re: [R] Encodage, console et mode OEM

Posté : lun. 30 déc. 2019 16:07
par Tlem
Le code n'est pas totalement de moi. Il me semble que je me suis inspiré d'un bout de code du forum US (je crois).
D'ailleurs, je suis étonné de ne pas avoir indiqué la source. :?

Re: [R] Encodage, console et mode OEM

Posté : lun. 30 déc. 2019 18:47
par jchd
Attention quand même : le retour du type "str" fait référence à une page de code, ce n'est PAS de l'Unicode. Les chaînes AutoIt utilisent le jeu UCS2, qui est la restriction d'Unicode au BMP (Basic Multilingual Plane) et emploie des codepoints sur 16 bits.

AutoIt fait silencieusement des conversions de codepage à UCS2 ou inversement dans pas mal de fonctions chaîne et aussi lors de DllCall. Le "bon" type est wstr et là on est sûr qu'il n'y a pas de bidouillage "sous le capot".

Re: [..] Encodage, console et mode OEM

Posté : mar. 31 déc. 2019 08:11
par DimVar
Tlem a écrit : lun. 30 déc. 2019 13:58
DimVar a écrit : lun. 30 déc. 2019 11:42 Si on fait un bête "DIR" sous la console et que l'on copie-colle le résultat sous Windows (dans notepad par ex), on obtient des caractères non pris en charge et mal "transformé".
Pour infos, sur mon PC qui est sous Windows 10x64 Pro, je n'ai pas ce comportement. Un Copié/Collé d'une console DOS me transfert bien les caractères accentués dans le Notepad de Windows. ^^

Edit : Je viens de faire la manip sur une VM en Windows 7 et pareil, les caractères accentués sont bien là. :P
Corrigé.