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 tekencoderen.

Wat is bestandscoderen en waarom is het belangrijk?

VS Code beheert de interface tussen een menselijke invoeren tekenreeksen in een buffer en het lezen/schrijven van bytes blokken van bytes naar het bestandssysteem. Wanneer VS Code een bestand opgeslagen, wordt een tekstcoderen gebruikt om te bepalen welke bytes elk teken wordt. Zie voor meer informatie about_Character_Encoding.

Op dezelfde manier moet wanneer PowerShell een script wordt uitgevoerd, de bytes in een bestand worden geconverkeerd naar tekens om het bestand opnieuw te reconstrueren in een PowerShell-programma. Omdat VS Code het bestand schrijft en PowerShell het bestand leest, moeten ze hetzelfde coderingssysteem gebruiken. Dit proces van het parseren van een PowerShell-script gaat: -> -> bytestekenstokens -> abstract syntaxisstructuur -> uitvoeren.

VS Code en PowerShell worden beide geïnstalleerd met een logische standaardconfiguratie voor codering. De standaardcoderen die door PowerShell wordt gebruikt, is echter gewijzigd met de release van PowerShell 6. Om ervoor te zorgen dat u geen problemen hebt 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 overeen komt met de verwachte codering van PowerShell. PowerShell kan de bestandscoderen niet automatisch bepalen.

De kans is groter dat u coderingsproblemen hebt wanneer u tekens gebruikt die niet voorkomen in de 7-bits ASCII-tekenset. Bijvoorbeeld:

  • Uitgebreide tekens zonder letter, zoals em-dash ( ), niet-brekende spatie ( ) of dubbele aanhalingstekens links ( " )
  • 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 in de standaardinstellingen. Voor PowerShell 5.1 en lager is de standaardcoderen anders dan die van VS Code.
  • Een andere editor heeft het bestand in een nieuwe codering geopend en overschreven. Dit gebeurt vaak met de ISE.
  • Het bestand wordt ingecheckt bij broncodebeheer in een codering die verschilt van wat VS Code of PowerShell verwacht. Dit kan gebeuren wanneer samenwerkers editors met verschillende coderingsconfiguraties gebruiken.

Hoe u kunt zien wanneer u coderingsproblemen hebt

Vaak worden fouten bij het coderen van fouten in scripts als parseringsfouten gebruikt. 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 â&euro;"From $from â&euro;"To $recipient1 â&euro;"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 â&euro;" .

Enkele vreemde tekenreeksen die u mogelijk ziet zijn:

  • â&euro;" In plaats van
  • â&euro;" In plaats van
  • Ä2 In plaats van Ä
  • Â in plaats van (een niet-brekende ruimte)
  • Ã&copy; In plaats van é

Deze handige referentie bevat de algemene patronen die duiden op een probleem met UTF-8/Windows-1252-codering.

Hoe de PowerShell-extensie in VS Code communiceert met coderingen

De PowerShell-extensie communiceert op verschillende manieren met scripts:

  1. Wanneer scripts worden bewerkt in VS Code, wordt de inhoud door VS Code naar de extensie verzonden. Het Language Server Protocol verplicht dat deze inhoud wordt overgedragen in UTF-8. Daarom is het niet mogelijk dat de extensie de verkeerde codering krijgt.
  2. Wanneer scripts rechtstreeks in de geïntegreerde console worden uitgevoerd, worden ze rechtstreeks uit het bestand gelezen door PowerShell. Als de codering van PowerShell verschilt van die van VS Code, kan er hier iets fout gaan.
  3. 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 wordt standaard ingesteld op UTF-8-codering, maar gebruikt het byte-ordertekenof de bomdetectie om de juiste codering te selecteren.

Het probleem treedt op wanneer wordt aangenomen dat bom-less-indelingen worden gecodeerd (zoals UTF-8 zonder bom en Windows-1252). De PowerShell-extensie wordt standaard ingesteld op UTF-8. De extensie kan de coderingsinstellingen van VS Code niet wijzigen. Zie probleem #824voor meer informatie.

De juiste codering kiezen

Verschillende systemen en toepassingen kunnen verschillende coderingen gebruiken:

  • In .NET Standard, op het web en in de Linux-wereld is UTF-8 nu de dominante codering.
  • Veel .NET Framework gebruiken UTF-16. Om historische redenen wordt dit soms 'Unicode' genoemd, een term die nu verwijst naar een brede standaard die zowel UTF-8 als UTF-16 bevat.
  • Op Windows blijven veel native toepassingen die unicode vooraf gaan standaard Windows-1252 gebruiken.

Unicode-coderingen hebben ook het concept van een byte-order mark (BOM). BOM's worden aan het begin van de tekst uitgevoerd om een decoder te vertellen welke codering van de tekst wordt gebruikt. Voor coderingen met meerdere byten geeft de bom ook de endianiteit van de codering aan. BOM's zijn ontworpen om bytes te zijn die zelden voorkomen in niet-Unicode-tekst, zodat u redelijk kunt raden dat tekst Unicode is wanneer er een bom aanwezig is.

BOM's zijn optioneel en de acceptatie ervan is niet zo populair in de Linux-wereld omdat overal een betrouwbare conventie van UTF-8 wordt gebruikt. Bij de meeste Linux-toepassingen wordt ervan uitgegaan dat tekstinvoer is gecodeerd in UTF-8. Hoewel veel Linux-toepassingen een stuklijst herkennen en correct verwerken, leidt een getal niet tot artefacten in tekst die met deze toepassingen worden bewerkt.

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 werkt in linux-gekoppelde contexten, moet u de voorkeur geven aan UTF-8 zonder bom.
  • Windows-1252 en latin-1 zijn in feite verouderde coderingen die u zo mogelijk moet vermijden. Sommige oudere toepassingen Windows kunnen er echter afhankelijk van zijn.
  • Het is ook belangrijk om te weten dat script-ondertekening coderingsafhankelijkis, wat betekent dat een wijziging van de codering in een ondertekend script moet worden vertekend.

VS Code configureren

De standaardcoderen van VS Code is UTF-8 zonder bom.

Als u de codering van VS Codewilt instellen, gaat u naar de VS Code-instellingen(Ctrl + ,) en stelt u de instelling "files.encoding" in:

"files.encoding": "utf8bom"

Enkele mogelijke waarden zijn:

  • utf8: [UTF-8] zonder bom
  • utf8bom: [UTF-8] met bom
  • utf16le: Little endian [UTF-16]
  • utf16be: Big endian [UTF-16]
  • windows1252: [Windows-1252]

Als het goed is, ziet u een vervolgkeuzekeuze voor deze in de GUI-weergave, of voltooiingen hiervoor in de JSON-weergave.

U kunt indien mogelijk ook het volgende toevoegen aan autodetect-codering:

"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 veld te [<language-name>] plaatsen. Bijvoorbeeld:

"[powershell]": {
    "files.encoding": "utf8bom",
    "files.autoGuessEncoding": true
}

U kunt ook overwegen om de Gremlins-tracker te installeren voor Visual Studio Code. In deze extensie worden bepaalde Unicode-tekens zichtbaar die eenvoudig kunnen worden beschadigd, omdat ze onzichtbaar zijn of lijken op andere normale tekens.

PowerShell configureren

De standaardcoderen van PowerShell is afhankelijk van de versie:

  • In PowerShell 6+ is de standaardcoderen UTF-8 zonder bom op alle platforms.
  • In Windows PowerShell is de standaardcoderen meestal Windows-1252, een uitbreiding van latin-1,ook wel ISO 8859-1 genoemd.

In PowerShell 5+ vindt u de standaardcoderen als de volgende:

[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 wat de codering van uw PowerShell-sessie de gevolg is van een script zonder een 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
}

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:

Het is niet mogelijk om PowerShell af te dwingen een specifieke invoercoderen te gebruiken. PowerShell 5.1 en lager, die wordt uitgevoerd op Windows met de locale ingesteld op en-US, wordt standaard ingesteld op Windows-1252-codering wanneer er geen bom is. Andere instellingen voor de lokale instellingen 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 gebruikt voor PowerShell-scripts, kunnen worden beïnvloed door uw coderingskeuzes of uw scripts opnieuw coderen naar een andere codering.

Bestaande scripts

Scripts die al op het bestandssysteem staan, 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 VS Code-codering 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 Integrated Scripting Environment (ISE) van PowerShell

Als u ook scripts bewerkt met de PowerShell ISE, moet u daar uw coderingsinstellingen synchroniseren.

De ISE moet een bom eren, maar het is ook mogelijk om reflectie te gebruiken om de codering in te stellen. Houd er rekening mee dat dit niet wordt persistent gemaakt tussen opstartstarts.

Broncodebeheersoftware

Sommige hulpprogramma's voor broncodebeheer, zoals git, negeren coderingen; Git houdt alleen de bytes bij. Andere, zoals Azure DevOps of Mercurial, zijn dat mogelijk niet. Zelfs sommige git-hulpprogramma's zijn afhankelijk van het decoderen van tekst.

Als dit het geval is, moet u het volgende doen:

  • Configureer de tekstcoderen in uw broncodebeheer, op basis van uw VS Code-configuratie.
  • Zorg ervoor dat al uw bestanden zijn ingecheckt bij broncodebeheer in de relevante codering.
  • Wees op uw hoede voor wijzigingen in de codering die is ontvangen via broncodebeheer. Een belangrijk teken van dit is een diff waarmee wijzigingen worden aangegeven, maar waar niets lijkt te zijn gewijzigd (omdat bytes maar tekens niet hebben).

Omgevingen van deelnemers

Zorg er niet alleen voor dat uw samenwerkers van bestanden die u deelt, geen instellingen hebben die uw codering overschrijven door PowerShell-bestanden opnieuw te coderen.

Andere programma's

Elk ander programma dat een PowerShell-script leest of schrijft, kan het opnieuw coderen.

Een aantal voorbeelden:

  • Gebruik het klembord om een script te kopiëren en plakken. Dit is gebruikelijk in scenario's zoals:
    • Een script kopiëren naar een VM
    • 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
    • Een 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 bestands share

Sommige van deze hulpprogramma's hebben te maken met bytes in plaats van tekst, maar andere bieden coderingsconfiguraties. In die gevallen waarin u een codering moet configureren, moet u deze hetzelfde maken als de codering van de editor om problemen te voorkomen.

Andere resources voor codering in PowerShell

Er zijn nog enkele andere goede berichten over het coderen en configureren van codering in PowerShell die de moeite waard zijn om te lezen: