Présentation de l’encodage de fichiers dans VS Code et PowerShell
Lorsque vous utilisez VS Code pour créer et modifier des scripts PowerShell, il est important que vos fichiers soient enregistrés à l’aide du format d’encodage de caractères correct.
Qu’est-ce que l’encodage de fichier et pourquoi est-il important ?
VS Code gère l’interface entre une chaîne de caractères entrante humaine dans une mémoire tampon et des blocs de lecture/écriture d’octets dans le système de fichiers. Lorsque VS Code enregistre un fichier, il utilise un encodage de texte pour déterminer les octets que chaque caractère devient. Pour plus d’informations, consultez about_Character_Encoding.
De même, lorsque PowerShell exécute un script, il doit convertir les octets d’un fichier en caractères pour reconstruire le fichier dans un programme PowerShell. Étant donné que VS Code écrit le fichier et PowerShell lit le fichier, il doit utiliser le même système d’encodage. Ce processus d’analyse d’un script PowerShell est le suivant : octets ->caractères ->jetons -> arborescence de syntaxe abstraite ->d’exécution.
VS Code et PowerShell sont installés avec une configuration d’encodage par défaut sensible. Toutefois, l’encodage par défaut utilisé par PowerShell a changé avec la version de PowerShell 6. Pour vous assurer que vous n’avez aucun problème à l’aide de PowerShell ou de l’extension PowerShell dans VS Code, vous devez configurer correctement vos paramètres VS Code et PowerShell.
Causes courantes des problèmes d’encodage
Les problèmes d’encodage se produisent lorsque l’encodage de VS Code ou de votre fichier de script ne correspond pas à l’encodage attendu de PowerShell. PowerShell n’a aucun moyen de déterminer automatiquement l’encodage de fichier.
Vous êtes plus susceptible d’avoir des problèmes d’encodage lorsque vous utilisez des caractères non dans le jeu de caractères ASCII 7 bits . Par exemple:
- Caractères non lettres étendus comme em-dash (
—
), espace non cassant ("
) - Caractères latins accentués (
É
,ü
) - Caractères non latins tels que cyrillique (
Д
,Ц
) - Caractères CJK (
本
,화
,が
)
Les raisons courantes des problèmes d’encodage sont les suivantes :
- Les encodages de VS Code et powerShell n’ont pas été modifiés par défaut. Pour PowerShell 5.1 et versions ultérieures, l’encodage par défaut est différent de celui de VS Code.
- Un autre éditeur a ouvert et remplacé le fichier dans un nouvel encodage. Cela se produit souvent avec l’ISE.
- Le fichier est archivé dans le contrôle de code source dans un encodage différent de ce que VS Code ou PowerShell attend. Cela peut se produire lorsque les collaborateurs utilisent des éditeurs avec différentes configurations d’encodage.
Comment savoir quand vous rencontrez des problèmes d’encodage
Souvent, les erreurs d’encodage se présentent comme des erreurs d’analyse dans les scripts. Si vous trouvez des séquences de caractères étranges dans votre script, il peut s’agir du problème. Dans l’exemple ci-dessous, un tiret en (–
) apparaît en tant que caractères â€"
:
Send-MailMessage : A positional parameter cannot be found that accepts argument 'Testing FuseMail SMTP...'.
At C:\Users\<User>\<OneDrive>\Development\PowerShell\Scripts\Send-EmailUsingSmtpRelay.ps1:6 char:1
+ Send-MailMessage â€"From $from â€"To $recipient1 â€"Subject $subject ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidArgument: (:) [Send-MailMessage], ParameterBindingException
+ FullyQualifiedErrorId : PositionalParameterNotFound,Microsoft.PowerShell.Commands.SendMailMessage
Ce problème se produit parce que VS Code encode le caractère –
en UTF-8 en tant qu’octets 0xE2 0x80 0x93
. Lorsque ces octets sont décodés en tant que Windows-1252, ils sont interprétés comme les caractères â€"
.
Voici quelques séquences de caractères étranges que vous pouvez voir :
-
â€"
au lieu de–
(en-tiret) -
â€"
au lieu de—
(un tiret em) -
Ä2
au lieu deÄ
-
Â
au lieu de -
é
au lieu deé
Cette référence pratique répertorie les modèles courants qui indiquent un problème d’encodage UTF-8/Windows-1252.
Comment l’extension PowerShell dans VS Code interagit avec les encodages
L’extension PowerShell interagit avec des scripts de plusieurs façons :
- Lorsque des scripts sont modifiés dans VS Code, le contenu est envoyé par VS Code à l’extension. Le protocole Language Server impose que ce contenu soit transféré dans UTF-8. Par conséquent, il n’est pas possible que l’extension obtienne l’encodage incorrect.
- Lorsque des scripts sont exécutés directement dans la console intégrée, ils sont lus directement à partir du fichier par PowerShell. Si l’encodage de PowerShell diffère de vs Code, quelque chose peut se tromper ici.
- Lorsqu’un script ouvert dans VS Code fait référence à un autre script qui n’est pas ouvert dans VS Code, l’extension revient au chargement du contenu de ce script à partir du système de fichiers. L’extension PowerShell utilise par défaut l’encodage UTF-8, mais utilise marque d’ordre d’octet, ou boM, détection pour sélectionner l’encodage approprié.
Le problème se produit lorsque l’encodage des formats sans boM (comme UTF-8 sans boM et Windows-1252). L’extension PowerShell est définie par défaut sur UTF-8. L’extension ne peut pas modifier les paramètres d’encodage de VS Code. Pour plus d’informations, consultez problème #824.
Choix de l’encodage approprié
Différents systèmes et applications peuvent utiliser différents encodages :
- Dans .NET Standard, sur le web et dans le monde Linux, UTF-8 est désormais l’encodage dominant.
- De nombreuses applications .NET Framework utilisent UTF-16 . Pour des raisons historiques, il s’agit parfois de « Unicode », terme qui fait maintenant référence à un large standard qui inclut à la fois UTF-8 et UTF-16.
- Sur Windows, de nombreuses applications natives qui précèdent Unicode continuent d’utiliser Windows-1252 par défaut.
Les encodages Unicode ont également le concept d’une marque d’ordre d’octet (BOM). Les machines virtuelles se produisent au début du texte pour indiquer à un décodeur qui encodage le texte est utilisé. Pour les encodages multioctets, le boM indique également endianness de l’encodage. Les boMs sont conçues pour être des octets qui se produisent rarement dans du texte non Unicode, ce qui permet de deviner raisonnablement que le texte est Unicode lorsqu’un BOM est présent.
Les boMs sont facultatives et leur adoption n’est pas aussi populaire dans le monde Linux, car une convention fiable de UTF-8 est utilisée partout. La plupart des applications Linux supposent que l’entrée de texte est encodée en UTF-8. Bien que de nombreuses applications Linux reconnaissent et gèrent correctement un boM, un nombre n’entraîne pas d’artefacts dans le texte manipulé avec ces applications.
Par conséquent,:
- Si vous travaillez principalement avec des applications Windows et Windows PowerShell, vous devez préférer un encodage comme UTF-8 avec boM ou UTF-16.
- Si vous travaillez sur plusieurs plateformes, vous devez préférer UTF-8 avec boM.
- Si vous travaillez principalement dans des contextes associés à Linux, vous devez préférer UTF-8 sans boM.
- Windows-1252 et latin-1 sont essentiellement des encodages hérités que vous devez éviter si possible. Toutefois, certaines applications Windows plus anciennes peuvent dépendre d’elles.
- Il est également important de noter que la signature de script est dépendant de l’encodage, ce qui signifie qu’un changement d’encodage sur un script signé nécessite la démission.
Configuration de VS Code
L’encodage par défaut de VS Code est UTF-8 sans boM.
Pour définir d’encodage de VS Code, accédez aux paramètres VS Code (Ctrl+,) et définissez le paramètre "files.encoding"
:
"files.encoding": "utf8bom"
Certaines valeurs possibles sont les suivantes :
-
utf8
: [UTF-8] sans boM -
utf8bom
: [UTF-8] avec boM -
utf16le
: Little endian [UTF-16] -
utf16be
: Big endian [UTF-16] -
windows1252
: [Windows-1252]
Vous devez obtenir une liste déroulante pour cela dans la vue GUI, ou des achèvements pour celui-ci dans la vue JSON.
Vous pouvez également ajouter les éléments suivants à l’encodage automatique lorsque cela est possible :
"files.autoGuessEncoding": true
Si vous ne souhaitez pas que ces paramètres affectent tous les types de fichiers, VS Code autorise également les configurations par langage. Créez un paramètre spécifique à la langue en plaçant les paramètres dans un champ [<language-name>]
. Par exemple:
"[powershell]": {
"files.encoding": "utf8bom",
"files.autoGuessEncoding": true
}
Vous pouvez également envisager d’installer le suivi Gremlins pour Visual Studio Code. Cette extension révèle certains caractères Unicode qui sont facilement endommagés, car ils sont invisibles ou ressemblent à d’autres caractères normaux.
Configuration de PowerShell
L’encodage par défaut de PowerShell varie en fonction de la version :
- Dans PowerShell 6+, l’encodage par défaut est UTF-8 sans boM sur toutes les plateformes.
- Dans Windows PowerShell, l’encodage par défaut est généralement Windows-1252, qui est une extension de latin-1 (également appelé ISO 8859-1).
Dans PowerShell 5+, vous trouverez votre encodage par défaut avec ceci :
[psobject].Assembly.GetTypes() | Where-Object { $_.Name -eq 'ClrFacade'} |
ForEach-Object {
$_.GetMethod('GetDefaultEncoding', [System.Reflection.BindingFlags]'nonpublic,static').Invoke($null, @())
}
Le script suivant peut être utilisé pour déterminer l’encodage de votre session PowerShell déduit pour un script sans boM.
$badBytes = [byte[]]@(0xC3, 0x80)
$utf8Str = [System.Text.Encoding]::UTF8.GetString($badBytes)
$bytes = [System.Text.Encoding]::ASCII.GetBytes('Write-Output "') + [byte[]]@(0xC3, 0x80) + [byte[]]@(0x22)
$path = Join-Path ([System.IO.Path]::GetTempPath()) 'encodingtest.ps1'
try
{
[System.IO.File]::WriteAllBytes($path, $bytes)
switch (& $path)
{
$utf8Str
{
return 'UTF-8'
break
}
default
{
return 'Windows-1252'
break
}
}
}
finally
{
Remove-Item $path
}
Il est possible de configurer PowerShell pour utiliser un encodage donné plus généralement à l’aide des paramètres de profil. Consultez les articles suivants :
- @mklement0réponse sur l’encodage PowerShell sur Stack Overflow.
- @rkeithhillbillet de blog sur la gestion des entrées UTF-8 sans boM dans PowerShell.
Il n’est pas possible de forcer PowerShell à utiliser un encodage d’entrée spécifique. PowerShell 5.1 et versions ultérieures, en cours d’exécution sur Windows avec les paramètres régionaux définis sur en-US, est défini par défaut sur l’encodage Windows-1252 lorsqu’il n’y a pas de boM. D’autres paramètres régionaux peuvent utiliser un encodage différent. Pour garantir l’interopérabilité, il est préférable d’enregistrer des scripts dans un format Unicode avec un boM.
Important
Tous les autres outils que vous avez qui touchent les scripts PowerShell peuvent être affectés par vos choix d’encodage ou réencodez vos scripts vers un autre encodage.
Scripts existants
Les scripts déjà présents sur le système de fichiers doivent peut-être être réencodés dans votre nouvel encodage choisi. Dans la barre inférieure de VS Code, vous verrez l’étiquette UTF-8. Cliquez dessus pour ouvrir la barre d’action et sélectionnez Enregistrer avec encodage. Vous pouvez désormais choisir un nouvel encodage pour ce fichier. Pour obtenir des instructions complètes, consultez d’encodage de VS Code.
Si vous devez réencoder plusieurs fichiers, vous pouvez utiliser le script suivant :
Get-ChildItem *.ps1 -Recurse | ForEach-Object {
$content = Get-Content -Path $_
Set-Content -Path $_.Fullname -Value $content -Encoding UTF8 -PassThru -Force
}
Environnement de script intégré PowerShell (ISE)
Si vous modifiez également des scripts à l’aide de PowerShell ISE, vous devez synchroniser vos paramètres d’encodage là-bas.
L’ISE doit honorer un boM, mais il est également possible d’utiliser la réflexion pour définir l’encodage. Notez que cela ne serait pas persistant entre les start-ups.
Logiciel de contrôle de code source
Certains outils de contrôle de code source, tels que git, ignorent les encodages ; git suit simplement les octets. D’autres, comme Azure DevOps ou Mercurial, peuvent ne pas le faire. Même certains outils git reposent sur le décodage de texte.
Lorsque c’est le cas, assurez-vous de :
- Configurez l’encodage de texte dans votre contrôle de code source pour qu’il corresponde à votre configuration VS Code.
- Vérifiez que tous vos fichiers sont archivés dans le contrôle de code source dans l’encodage approprié.
- Soyez méfiant des modifications apportées à l’encodage reçu par le biais du contrôle de code source. Un signe clé de ceci est un différences indiquant les modifications, mais où rien ne semble avoir changé (car les octets ont mais les caractères n’ont pas).
Environnements des collaborateurs
En plus de configurer le contrôle de code source, assurez-vous que vos collaborateurs sur les fichiers que vous partagez n’ont pas de paramètres qui remplacent votre encodage en réécodant les fichiers PowerShell.
Autres programmes
Tout autre programme qui lit ou écrit un script PowerShell peut le réencoder.
Voici quelques exemples :
- Utilisation du Presse-papiers pour copier et coller un script. Ceci est courant dans les scénarios tels que :
- Copie d’un script dans une machine virtuelle
- Copie d’un script à partir d’un e-mail ou d’une page web
- Copie d’un script dans ou hors d’un document Microsoft Word ou PowerPoint
- Autres éditeurs de texte, tels que :
- Bloc-notes
- entrain
- Tout autre éditeur de script PowerShell
- Utilitaires d’édition de texte, comme :
Get-Content
/Set-Content
/Out-File
- Opérateurs de redirection PowerShell tels que
>
et>>
sed
/awk
- Programmes de transfert de fichiers, comme :
- Un navigateur web, lors du téléchargement de scripts
- Un partage de fichiers
Certains de ces outils traitent en octets plutôt que du texte, mais d’autres offrent des configurations d’encodage. Dans les cas où vous devez configurer un encodage, vous devez le faire de la même façon que votre encodage de l’éditeur pour éviter les problèmes.
Autres ressources sur l’encodage dans PowerShell
Il existe quelques autres publications intéressantes sur l’encodage et la configuration de l’encodage dans PowerShell qui valent une lecture :
- about_Character_Encoding
- @mklement0résumé de l’encodage PowerShell sur stack Overflow
- Problèmes précédents ouverts sur VS Code-PowerShell pour les problèmes d’encodage :
- Le classique Joel on Software écrire sur le Unicode
- encodage dans le .NET Standard