Informatie over bestandscodering in VS Code en PowerShell
Wanneer u VS Code gebruikt om PowerShell-scripts te maken en te bewerken, is het belangrijk dat uw bestanden worden opgeslagen met de juiste indeling voor tekencodering.
Wat is bestandscodering en waarom is het belangrijk?
VS Code beheert de interface tussen een mens die tekenreeksen invoert in een buffer en lees-/schrijfblokken van bytes naar het bestandssysteem. Wanneer VS Code een bestand opslaat, wordt een tekstcodering gebruikt om te bepalen welke bytes elk teken wordt. Zie about_Character_Encoding voor meer informatie.
Op dezelfde manier moet, wanneer PowerShell een script uitvoert, de bytes in een bestand converteren naar tekens om het bestand te reconstrueren in een PowerShell-programma. Omdat VS Code het bestand schrijft en PowerShell het bestand leest, moeten ze hetzelfde coderingssysteem gebruiken. Dit proces voor het parseren van een PowerShell-script gaat als volgt: bytes ->characters ->tokens ->abstracte syntaxisstructuur ->execution.
Zowel VS Code als PowerShell worden geïnstalleerd met een verstandige standaardcoderingsconfiguratie. De standaardcodering die door PowerShell wordt gebruikt, is echter gewijzigd met de release van PowerShell 6. Om ervoor te zorgen dat u geen problemen ondervindt met het gebruik van PowerShell of de PowerShell-extensie in VS Code, moet u uw VS Code- en PowerShell-instellingen correct configureren.
Veelvoorkomende oorzaken van coderingsproblemen
Coderingsproblemen treden op wanneer de codering van VS Code of uw scriptbestand niet overeenkomt met de verwachte codering van PowerShell. PowerShell kan de bestandscodering niet automatisch bepalen.
U hebt waarschijnlijk meer coderingsproblemen wanneer u tekens gebruikt die niet in de 7-bits ASCII-tekenset staan. Voorbeeld:
- Uitgebreide niet-lettertekens zoals em-streepje (
—
), niet-brekende spatie ("
) - Latijnse tekens met accenten (
É
,ü
) - Niet-Latijnse tekens zoals Cyrillisch (
Д
,Ц
) - CJK-tekens (
本
,화
,が
)
Veelvoorkomende redenen voor coderingsproblemen zijn:
- De coderingen van VS Code en PowerShell zijn niet gewijzigd van de standaardinstellingen. Voor PowerShell 5.1 en lager verschilt de standaardcodering van VS Code.
- Een andere editor heeft het bestand geopend en overschreven in een nieuwe codering. Dit gebeurt vaak met de ISE.
- Het bestand wordt ingecheckt in broncodebeheer in een codering die verschilt van wat VS Code of PowerShell verwacht. Dit kan gebeuren wanneer medewerkers editors gebruiken met verschillende coderingsconfiguraties.
Hoe kunt u zien wanneer u problemen hebt met coderen
Vaak komen coderingsfouten voor als parseringsfouten in scripts. Als u vreemde tekenreeksen in uw script vindt, kan dit het probleem zijn. In het onderstaande voorbeeld wordt een en-dash (–
) weergegeven als de tekens â€"
:
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
Dit probleem treedt op omdat VS Code het teken –
in UTF-8 codeert als de bytes 0xE2 0x80 0x93
. Wanneer deze bytes worden gedecodeerd als Windows-1252, worden ze geïnterpreteerd als de tekens â€"
.
Enkele vreemde tekenreeksen die u mogelijk ziet, zijn:
â€"
in plaats van–
(een en-dash)â€"
in plaats van—
(een em-dash)Ä2
In plaats vanÄ
Â
in plaats vané
In plaats vané
Deze handige naslaginformatie bevat de algemene patronen die duiden op een UTF-8/Windows-1252-coderingsprobleem.
Hoe de PowerShell-extensie in VS Code communiceert met coderingen
De PowerShell-extensie communiceert op verschillende manieren met scripts:
- Wanneer scripts worden bewerkt in VS Code, wordt de inhoud door VS Code naar de extensie verzonden. Het Language Server Protocol vereist dat deze inhoud wordt overgedragen in UTF-8. Daarom is het niet mogelijk dat de extensie de verkeerde codering krijgt.
- Wanneer scripts rechtstreeks in de geïntegreerde console worden uitgevoerd, worden ze rechtstreeks vanuit het bestand gelezen door PowerShell. Als de codering van PowerShell verschilt van vs Code, kan er hier iets mis gaan.
- Wanneer een script dat is geopend in VS Code verwijst naar een ander script dat niet is geopend in VS Code, valt de extensie terug op het laden van de inhoud van dat script vanuit het bestandssysteem. De PowerShell-extensie is standaard ingesteld op UTF-8-codering, maar maakt gebruik van bytevolgordemarkering of bomdetectie om de juiste codering te selecteren.
Het probleem treedt op wanneer wordt aangenomen dat de codering van bomloze indelingen (zoals UTF-8 zonder bom en Windows-1252). De PowerShell-extensie is standaard ingesteld op UTF-8. De extensie kan de coderingsinstellingen van VS Code niet wijzigen. Zie probleem 824 voor meer informatie.
De juiste codering kiezen
Verschillende systemen en toepassingen kunnen verschillende coderingen gebruiken:
- In .NET Standard, op internet en in de Linux-wereld is UTF-8 nu de dominante codering.
- Veel .NET Framework-toepassingen maken gebruik van UTF-16. Om historische redenen wordt dit ook wel Unicode genoemd, een term die nu verwijst naar een brede standaard met zowel UTF-8 als UTF-16.
- In Windows blijven veel systeemeigen toepassingen die vóór Unicode predate Windows-1252 standaard gebruiken.
Unicode-coderingen hebben ook het concept van een byte-ordermarkering (BOM). BOM's vinden plaats aan het begin van de tekst om een decoder te vertellen welke codering van de tekst wordt gebruikt. Voor coderingen met meerdere bytes geeft de BOM ook de endianiteit van de codering aan. BOM's zijn ontworpen als bytes die zelden voorkomen in niet-Unicode-tekst, waardoor een redelijke schatting is dat tekst Unicode is wanneer er een bom aanwezig is.
BOM's zijn optioneel en hun acceptatie is niet zo populair in de Linux-wereld, omdat overal een betrouwbare conventie van UTF-8 wordt gebruikt. In de meeste Linux-toepassingen wordt ervan uitgegaan dat tekstinvoer is gecodeerd in UTF-8. Hoewel veel Linux-toepassingen een stuklijst herkennen en correct verwerken, is een getal niet mogelijk, wat leidt tot artefacten in tekst die met deze toepassingen wordt gemanipuleerd.
Daarom:
- Als u voornamelijk met Windows-toepassingen en Windows PowerShell werkt, moet u de voorkeur geven aan een codering zoals UTF-8 met BOM of UTF-16.
- Als u op verschillende platforms werkt, moet u de voorkeur geven aan UTF-8 met BOM.
- Als u voornamelijk in Linux-contexten werkt, moet u de voorkeur geven aan UTF-8 zonder bom.
- Windows-1252 en latin-1 zijn in wezen verouderde coderingen die u indien mogelijk moet vermijden. Sommige oudere Windows-toepassingen zijn echter mogelijk afhankelijk van deze toepassingen.
- Het is ook de moeite waard om te vermelden dat ondertekening van scripts afhankelijk is van codering, wat betekent dat een wijziging van codering voor een ondertekend script moet worden afgetrokken.
VS Code configureren
De standaardcodering van VS Code is UTF-8 zonder bom.
Als u de codering van VS Code wilt instellen, gaat u naar de VS Code-instellingen (Ctrl+,) en stelt u de "files.encoding"
instelling in:
"files.encoding": "utf8bom"
Enkele mogelijke waarden zijn:
utf8
: [UTF-8] zonder bomutf8bom
: [UTF-8] met BOMutf16le
: Little endian [UTF-16]utf16be
: Big endian [UTF-16]windows1252
: [Windows-1252]
U krijgt een vervolgkeuzelijst voor dit in de GUI-weergave of voltooiingen voor deze in de JSON-weergave.
U kunt ook het volgende toevoegen aan automatische detectie, indien mogelijk:
"files.autoGuessEncoding": true
Als u niet wilt dat deze instellingen van invloed zijn op alle bestandstypen, staat VS Code ook configuraties per taal toe. Maak een taalspecifieke instelling door instellingen in een [<language-name>]
veld te plaatsen. Voorbeeld:
"[powershell]": {
"files.encoding": "utf8bom",
"files.autoGuessEncoding": true
}
U kunt ook overwegen om de Gremlins-tracker voor Visual Studio Code te installeren. Deze extensie toont bepaalde Unicode-tekens die gemakkelijk beschadigd zijn omdat ze onzichtbaar zijn of eruitzien als andere normale tekens.
PowerShell configureren
De standaardcodering van PowerShell varieert afhankelijk van de versie:
- In PowerShell 6+ is de standaardcodering UTF-8 zonder bom op alle platforms.
- In Windows PowerShell is de standaardcodering meestal Windows-1252, een uitbreiding van latin-1 (ook wel ISO 8859-1 genoemd).
In PowerShell 5+ kunt u uw standaardcodering vinden met deze:
[psobject].Assembly.GetTypes() | Where-Object { $_.Name -eq 'ClrFacade'} |
ForEach-Object {
$_.GetMethod('GetDefaultEncoding', [System.Reflection.BindingFlags]'nonpublic,static').Invoke($null, @())
}
Het volgende script kan worden gebruikt om te bepalen welke codering van uw PowerShell-sessie wordt afgeleid voor een script zonder een stuklijst.
$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
}
Het is mogelijk om PowerShell te configureren voor het gebruik van een bepaalde codering in het algemeen met behulp van profielinstellingen. Zie de volgende artikelen:
- @mklement0's antwoord over PowerShell-codering op StackOverflow.
- @rkeithhillBlogpost over het omgaan met BOM-less UTF-8-invoer in PowerShell.
Het is niet mogelijk om PowerShell te dwingen een specifieke invoercodering te gebruiken. PowerShell 5.1 en lager, uitgevoerd op Windows met de landinstelling ingesteld op en-US, wordt standaard ingesteld op Windows-1252-codering wanneer er geen bom is. Andere landinstellingen kunnen een andere codering gebruiken. Om interoperabiliteit te garanderen, kunt u scripts het beste opslaan in een Unicode-indeling met een BOM.
Belangrijk
Andere hulpprogramma's die u hebt die powerShell-scripts aanraken, kunnen worden beïnvloed door uw coderingskeuzes of het opnieuw coderen van uw scripts naar een andere codering.
Bestaande scripts
Scripts die zich al op het bestandssysteem bevinden, moeten mogelijk opnieuw worden gecodeerd naar de nieuwe gekozen codering. In de onderste balk van VS Code ziet u het label UTF-8. Klik erop om de actiebalk te openen en Selecteer Opslaan met codering. U kunt nu een nieuwe codering voor dat bestand kiezen. Zie de codering van VS Code voor volledige instructies.
Als u meerdere bestanden opnieuw moet coderen, kunt u het volgende script gebruiken:
Get-ChildItem *.ps1 -Recurse | ForEach-Object {
$content = Get-Content -Path $_
Set-Content -Path $_.Fullname -Value $content -Encoding UTF8 -PassThru -Force
}
De PowerShell Integrated Scripting Environment (ISE)
Als u ook scripts bewerkt met powershell ISE, moet u daar uw coderingsinstellingen synchroniseren.
De ISE moet een BOM respecteren, maar het is ook mogelijk om reflectie te gebruiken om de codering in te stellen. Houd er rekening mee dat dit niet tussen start-ups zou worden bewaard.
Broncodebeheersoftware
Sommige hulpprogramma's voor broncodebeheer, zoals Git, negeren coderingen; Git houdt alleen de bytes bij. Andere, zoals Azure DevOps of Mercurial, kunnen dat niet. Zelfs sommige git-hulpprogramma's zijn afhankelijk van het decoderen van tekst.
Als dit het geval is, controleert u het volgende:
- Configureer de tekstcodering in uw broncodebeheer zodat deze overeenkomt met uw VS Code-configuratie.
- Zorg ervoor dat al uw bestanden in broncodebeheer zijn ingecheckt in de relevante codering.
- Wees voorzichtig met wijzigingen in de codering die via broncodebeheer is ontvangen. Een sleutelteken hiervan is een diff die wijzigingen aangeeft, maar waar niets lijkt te zijn gewijzigd (omdat bytes maar tekens niet hebben).
Omgevingen van samenwerkers
Zorg ervoor dat uw medewerkers over alle bestanden die u deelt, geen instellingen hebben die uw codering overschrijven door PowerShell-bestanden opnieuw te coderen, bovenop het configureren van broncodebeheer.
Andere programma's
Elk ander programma dat een PowerShell-script leest of schrijft, kan het opnieuw coderen.
Enkele voorbeelden:
- Het Klembord gebruiken om een script te kopiëren en plakken. Dit is gebruikelijk in scenario's zoals:
- Een script kopiëren naar een VIRTUELE machine
- Een script kopiëren uit een e-mailbericht of webpagina
- Een script kopiëren naar of uit een Microsoft Word- of PowerPoint-document
- Andere teksteditors, zoals:
- Kladblok
- vim
- Elke andere PowerShell-scripteditor
- Hulpprogramma's voor tekstbewerking, zoals:
Get-Content
/Set-Content
/Out-File
- PowerShell-omleidingsoperators zoals
>
en>>
sed
/awk
- Programma's voor bestandsoverdracht, zoals:
- Een webbrowser bij het downloaden van scripts
- Een bestandsshare
Sommige van deze hulpprogramma's hebben betrekking op bytes in plaats van tekst, maar andere bieden coderingsconfiguraties. In gevallen waarin u een codering moet configureren, moet u deze hetzelfde maken als de codering van uw editor om problemen te voorkomen.
Andere resources voor codering in PowerShell
Er zijn enkele andere leuke berichten over codering en het configureren van codering in PowerShell die een lees waard zijn:
- about_Character_Encoding
- @mklement0Samenvatting van PowerShell-codering op StackOverflow
- Eerdere problemen die zijn geopend in VS Code-PowerShell voor coderingsproblemen:
- De klassieke Joel on Software schrijft over Unicode
- Codering in .NET Standard