Share via


Förstå filkodning i VS Code och PowerShell

När du använder VS Code för att skapa och redigera PowerShell-skript är det viktigt att filerna sparas med rätt teckenkodningsformat.

Vad är filkodning och varför är det viktigt?

VS Code hanterar gränssnittet mellan en människa som anger teckensträngar i en buffert och läser/skriver block med byte till filsystemet. När VS Code sparar en fil använder den en textkodning för att bestämma vilka byte varje tecken blir. Mer information finns i about_Character_Encoding.

På samma sätt måste byte i en fil konverteras till tecken när PowerShell kör ett skript för att rekonstruera filen till ett PowerShell-program. Eftersom VS Code skriver filen och PowerShell läser filen måste de använda samma kodningssystem. Den här processen för att parsa ett PowerShell-skript går: bytes ->characters ->tokens ->abstract syntax tree ->execution.

Både VS Code och PowerShell installeras med en lämplig standardkodningskonfiguration. Standardkodningen som används av PowerShell har dock ändrats med versionen av PowerShell 6. För att säkerställa att du inte har några problem med att använda PowerShell eller PowerShell-tillägget i VS Code måste du konfigurera VS Code- och PowerShell-inställningarna korrekt.

Vanliga orsaker till kodningsproblem

Kodningsproblem uppstår när kodningen av VS Code eller skriptfilen inte matchar den förväntade kodningen av PowerShell. Det finns inget sätt för PowerShell att automatiskt fastställa filkodningen.

Det är mer troligt att du har kodningsproblem när du använder tecken som inte finns i 7-bitars ASCII-teckenuppsättningen. Till exempel:

  • Utökade icke-bokstavstecken som em-dash (), icke-blanksteg ( ) eller vänster dubbla citattecken (")
  • Latinska accenttecken (É, ü)
  • Icke-latinska tecken som kyrilliska (Д, Ц)
  • CJK-tecken (, , )

Vanliga orsaker till kodningsproblem är:

  • Kodningarna för VS Code och PowerShell har inte ändrats från standardinställningarna. För PowerShell 5.1 och nedan skiljer sig standardkodningen från VS Code.
  • En annan redigerare har öppnat och skrivit över filen i en ny kodning. Detta sker ofta med ISE.
  • Filen checkas in i källkontrollen i en kodning som skiljer sig från vad VS Code eller PowerShell förväntar sig. Detta kan inträffa när medarbetare använder redigeringsprogram med olika kodningskonfigurationer.

Så här ser du när du har kodningsproblem

Ofta visas kodningsfel som parsningsfel i skript. Om du hittar konstiga teckensekvenser i skriptet kan det vara problemet. I exemplet nedan visas ett bindestreck () som tecknen â€":

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

Det här problemet beror på att VS Code kodar tecknet i UTF-8 som byte 0xE2 0x80 0x93. När dessa byte avkodas som Windows-1252 tolkas de som tecknen â&euro;".

Några konstiga teckensekvenser som du kan se är:

  • â&euro;" i stället för (ett bindestreck)
  • â&euro;" i stället för (ett em-dash)
  • Ä2 Istället för Ä
  • Â i stället   för (ett icke-blanksteg)
  • Ã&copy; Istället för é

Den här praktiska referensen visar de vanliga mönster som indikerar ett UTF-8/Windows-1252-kodningsproblem.

Hur PowerShell-tillägget i VS Code interagerar med kodningar

PowerShell-tillägget interagerar med skript på flera olika sätt:

  1. När skript redigeras i VS Code skickas innehållet av VS Code till tillägget. Language Server Protocol kräver att det här innehållet överförs i UTF-8. Därför är det inte möjligt för tillägget att få fel kodning.
  2. När skript körs direkt i den integrerade konsolen läss de direkt från filen av PowerShell. Om PowerShells kodning skiljer sig från VS Code kan något gå fel här.
  3. När ett skript som är öppet i VS Code refererar till ett annat skript som inte är öppet i VS Code, återgår tillägget till att läsa in skriptets innehåll från filsystemet. PowerShell-tillägget är som standard UTF-8-kodning, men använder byteordningsmarkering eller BOM-identifiering för att välja rätt kodning.

Problemet uppstår när du antar kodning av BOM-mindre format (som UTF-8 utan bom och Windows-1252). PowerShell-tillägget är som standard UTF-8. Tillägget kan inte ändra VS Code-kodningsinställningarna. Mer information finns i problem #824.

Välja rätt kodning

Olika system och program kan använda olika kodningar:

  • I .NET Standard, på webben och i Linux-världen är UTF-8 nu den dominerande kodningen.
  • Många .NET Framework-program använder UTF-16. Av historiska skäl kallas detta ibland "Unicode", en term som nu refererar till en bred standard som innehåller både UTF-8 och UTF-16.
  • I Windows fortsätter många inbyggda program som föregå Unicode att använda Windows-1252 som standard.

Unicode-kodningar har också begreppet byteordningsmärke (BOM). I början av texten visas information om vilken kodning texten använder. För kodningar med flera byte anger bommen också kodningens endianitet . BOM:er är utformade för att vara byte som sällan förekommer i icke-Unicode-text, vilket ger en rimlig gissning om att texten är Unicode när en strukturliste finns.

BPM är valfria och deras införande är inte lika populärt i Linux-världen eftersom en pålitlig konvention med UTF-8 används överallt. De flesta Linux-program förutsätter att textindata kodas i UTF-8. Även om många Linux-program känner igen och hanterar en strukturlista korrekt, gör inte ett tal det, vilket leder till artefakter i text som manipulerats med dessa program.

Därför:

  • Om du främst arbetar med Windows-program och Windows PowerShell bör du föredra en kodning som UTF-8 med BOM eller UTF-16.
  • Om du arbetar på flera plattformar bör du föredra UTF-8 med BOM.
  • Om du huvudsakligen arbetar i Linux-associerade kontexter bör du föredra UTF-8 utan BOM.
  • Windows-1252 och latin-1 är i stort sett äldre kodningar som du bör undvika om möjligt. Vissa äldre Windows-program kan dock vara beroende av dem.
  • Det är också värt att notera att skriptsignering är kodningsberoende, vilket innebär att en ändring av kodningen på ett signerat skript kräver avsägning.

Konfigurera VS Code

VS Code-standardkodningen är UTF-8 utan bom.

Om du vill ange VS Code-kodning går du till VS Code-inställningarna (Ctrl+) och anger inställningen"files.encoding":

"files.encoding": "utf8bom"

Några möjliga värden är:

  • utf8: [UTF-8] utan BOM
  • utf8bom: [UTF-8] med BOM
  • utf16le: Little endian [UTF-16]
  • utf16be: Stor endian [UTF-16]
  • windows1252: [Windows-1252]

Du bör få en listruta för detta i GUI-vyn eller slutföranden för den i JSON-vyn.

Du kan också lägga till följande för att identifiera kodning automatiskt när det är möjligt:

"files.autoGuessEncoding": true

Om du inte vill att de här inställningarna ska påverka alla filtyper tillåter VS Code även konfigurationer per språk. Skapa en språkspecifik inställning genom att placera inställningar i ett [<language-name>] fält. Till exempel:

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

Du kanske också vill överväga att installera Gremlins-spåraren för Visual Studio Code. Det här tillägget visar vissa Unicode-tecken som lätt skadas eftersom de är osynliga eller ser ut som andra normala tecken.

Konfigurera PowerShell

Standardkodningen för PowerShell varierar beroende på version:

  • I PowerShell 6+ är standardkodningen UTF-8 utan BOM på alla plattformar.
  • I Windows PowerShell är standardkodningen vanligtvis Windows-1252, vilket är ett tillägg av latin-1 (även kallat ISO 8859-1).

I PowerShell 5+ hittar du din standardkodning med följande:

[psobject].Assembly.GetTypes() | Where-Object { $_.Name -eq 'ClrFacade'} |
  ForEach-Object {
    $_.GetMethod('GetDefaultEncoding', [System.Reflection.BindingFlags]'nonpublic,static').Invoke($null, @())
  }

Följande skript kan användas för att avgöra vad som kodar powershell-sessionens slutsatsdragningar för ett skript utan en strukturlista.

$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
}

Det är möjligt att konfigurera PowerShell att använda en viss kodning mer allmänt med hjälp av profilinställningar. Mer information finns i följande artiklar:

Det går inte att tvinga PowerShell att använda en specifik indatakodning. PowerShell 5.1 och lägre, som körs i Windows med nationella inställningar inställda på en-US, är som standard Windows-1252-kodning när det inte finns någon strukturlista. Andra nationella inställningar kan använda en annan kodning. För att säkerställa samverkan är det bäst att spara skript i unicode-format med en strukturlista.

Viktigt!

Andra verktyg som du har som rör PowerShell-skript kan påverkas av dina kodningsalternativ eller koda om skripten till en annan kodning.

Befintliga skript

Skript som redan finns i filsystemet kan behöva kodas om till din nya valda kodning. I det nedre fältet i VS Code visas etiketten UTF-8. Klicka på den för att öppna åtgärdsfältet och välj Spara med kodning. Nu kan du välja en ny kodning för filen. Se VS Code-kodningen för fullständiga instruktioner.

Om du behöver koda om flera filer kan du använda följande skript:

Get-ChildItem *.ps1 -Recurse | ForEach-Object {
    $content = Get-Content -Path $_
    Set-Content -Path $_.Fullname -Value $content -Encoding UTF8 -PassThru -Force
}

Den integrerade skriptmiljön i PowerShell (ISE)

Om du också redigerar skript med Hjälp av PowerShell ISE måste du synkronisera kodningsinställningarna där.

ISE bör respektera en strukturlista, men det är också möjligt att använda reflektion för att ange kodningen. Observera att detta inte skulle sparas mellan nystartade företag.

Programvara för källkontroll

Vissa verktyg för källkontroll, till exempel git, ignorerar kodningar. git spårar bara byte. Andra, till exempel Azure DevOps eller Mercurial, kanske inte gör det. Även vissa git-baserade verktyg förlitar sig på avkodning av text.

När så är fallet kontrollerar du att du:

  • Konfigurera textkodningen i källkontrollen så att den matchar VS Code-konfigurationen.
  • Kontrollera att alla dina filer är incheckade i källkontrollen i relevant kodning.
  • Var försiktig med ändringar i kodningen som tas emot via källkontrollen. Ett nyckeltecken för detta är ett diff som anger ändringar men där ingenting verkar ha ändrats (eftersom byte har men tecken inte har det).

Medarbetares miljöer

Utöver att konfigurera källkontroll kontrollerar du att dina medarbetare på alla filer som du delar inte har inställningar som åsidosätter kodningen genom att koda om PowerShell-filer.

Andra program

Andra program som läser eller skriver ett PowerShell-skript kan koda om det.

Några exempel är:

  • Använda Urklipp för att kopiera och klistra in ett skript. Detta är vanligt i scenarier som:
    • Kopiera ett skript till en virtuell dator
    • Kopiera ett skript från ett e-postmeddelande eller en webbsida
    • Kopiera ett skript till eller från ett Microsoft Word- eller PowerPoint-dokument
  • Andra textredigerare, till exempel:
    • Anteckningar
    • vim
    • Alla andra PowerShell-skriptredigerare
  • Verktyg för textredigering, till exempel:
    • Get-Content/Set-Content/Out-File
    • PowerShell-omdirigeringsoperatorer som > och >>
    • sed/awk
  • Filöverföringsprogram, till exempel:
    • En webbläsare när skript laddas ned
    • En filresurs

Vissa av dessa verktyg hanterar byte i stället för text, men andra erbjuder kodningskonfigurationer. I de fall där du behöver konfigurera en kodning måste du göra den på samma sätt som redigeringsprogrammets kodning för att förhindra problem.

Andra resurser om kodning i PowerShell

Det finns några andra fina inlägg om kodning och konfiguration av kodning i PowerShell som är värda att läsa: