Principy kódování souborů ve VS Code a PowerShellu
Pokud k vytváření a úpravě skriptů PowerShellu používáte VS Code, je důležité, aby se vaše soubory ukládaly ve správném formátu kódování znaků.
Co je kódování souborů a proč je důležité?
VS Code spravuje rozhraní mezi člověkem, který zadává řetězce znaků do vyrovnávací paměti a bloků čtení a zápisu bajtů do systému souborů. Když VS Code uloží soubor, použije kódování textu k rozhodnutí, jaké bajty se jednotlivé znaky stanou. Další informace najdete v tématu about_Character_Encoding.
Podobně když PowerShell spustí skript, musí převést bajty v souboru na znaky, aby byl soubor rekonstruován do programu PowerShellu. Vzhledem k tomu, že VS Code zapisuje soubor a PowerShell soubor čte, musí použít stejný systém kódování. Tento proces analýzy skriptu PowerShellu probíhá: bajty ->characters -tokens ->>abstract syntax tree ->execution.
VS Code i PowerShell se instalují s rozumnou výchozí konfigurací kódování. Výchozí kódování používané prostředím PowerShell se ale změnilo ve verzi PowerShellu 6. Abyste měli jistotu, že ve VS Code nemáte problémy s používáním PowerShellu nebo rozšíření PowerShellu, musíte správně nakonfigurovat nastavení VS Code a PowerShellu.
Běžné příčiny problémů s kódováním
K problémům s kódováním dochází v případě, že kódování VS Code nebo soubor skriptu neodpovídá očekávanému kódování PowerShellu. PowerShell nemůže automaticky určit kódování souborů.
S větší pravděpodobností budete mít problémy s kódováním, když používáte znaky, které nejsou v 7bitové znakové sadě ASCII. Příklad:
- Rozšířené znaky bez písmen, jako jsou em-dash (
—
), mezera bez přerušení ("
) - Zvýrazněné znaky latinky (
É
,ü
) - Jiné než latinky, jako je cyrilice (
Д
,Ц
) - Znaky CJK (
本
,화
,が
)
Mezi běžné příčiny problémů s kódováním patří:
- Kódování VS Code a PowerShellu se nezměnilo z výchozích hodnot. Pro PowerShell 5.1 a níže se výchozí kódování liší od kódu VS Code.
- Jiný editor soubor otevřel a přepsal v novém kódování. K tomu často dochází u ise.
- Soubor je vrácen do správy zdrojového kódu v kódování, které se liší od toho, co VS Code nebo PowerShell očekává. K tomu může dojít, když spolupracovníci používají editory s různými konfiguracemi kódování.
Jak zjistit, kdy máte problémy s kódováním
Chyby kódování se často vyskytují jako analýzy chyb ve skriptech. Pokud ve skriptu najdete podivné sekvence znaků, může to být problém. V následujícím příkladu se jako znaky â€"
zobrazí pomlčka (–
):
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
K tomuto problému dochází, protože VS Code kóduje znak –
v UTF-8 jako bajty 0xE2 0x80 0x93
. Když jsou tyto bajty dekódovány jako Windows-1252, jsou interpretovány jako znaky â€"
.
Mezi podivné sekvence znaků, které se můžou zobrazit, patří:
â€"
–
místo (pomlčka)â€"
—
místo (pomlčka)Ä2
NamístoÄ
Â
é
Namístoé
Tento praktický odkaz obsahuje seznam běžných vzorů, které označují problém kódování UTF-8/Windows-1252.
Jak rozšíření PowerShellu ve VS Code komunikuje s kódováním
Rozšíření PowerShellu komunikuje se skripty mnoha způsoby:
- Při úpravách skriptů v editoru VS Code se obsah odešle do rozšíření VS Code. Protokol jazykového serveru vyžaduje, aby se tento obsah přenášel v UTF-8. Proto není možné, aby rozšíření získalo nesprávné kódování.
- Když se skripty spustí přímo v integrované konzole, powershell je přímo načte ze souboru. Pokud se kódování PowerShellu liší od VS Code, může se tady něco pokazit.
- Když skript otevřený ve VS Code odkazuje na jiný skript, který není otevřený ve VS Code, rozšíření se vrátí zpět k načtení obsahu skriptu ze systému souborů. Rozšíření PowerShellu ve výchozím nastavení používá kódování UTF-8, ale k výběru správného kódování používá znaménko pořadí bajtů nebo boM.
K tomuto problému dochází v případě, že za předpokladu kódování formátů bez boM a Windows-1252 (například UTF-8 bez BOM a Windows-1252). Výchozí rozšíření PowerShellu je UTF-8. Rozšíření nemůže změnit nastavení kódování VS Code. Další informace najdete v tématu problém č. 824.
Výběr správného kódování
Různé systémy a aplikace můžou používat různá kódování:
- V .NET Standard, na webu a na světě Linuxu, UTF-8 je nyní dominantní kódování.
- Mnoho aplikací rozhraní .NET Framework používá UTF-16. Z historických důvodů se tomu někdy říká "Unicode", termín, který nyní odkazuje na široký standard , který zahrnuje UTF-8 i UTF-16.
- V systému Windows ve výchozím nastavení používá mnoho nativních aplikací, které předepíše kódování Unicode, ve výchozím nastavení windows-1252.
Kódování Unicode má také koncept značky pořadí bajtů (BOM). Kusovníky se vyskytují na začátku textu, aby dekodér, který kóduje text, který používá. U kódování s více bajty označuje boM také endianitu kódování. Kusovníky jsou navržené tak, aby byly bajty, které se zřídka vyskytují v textu, který není unicode, což umožňuje rozumný odhad, že text je Unicode, když je k dispozici kusovník.
Kusovníky jsou volitelné a jejich přijetí není tak populární ve světě Linuxu, protože spolehlivé konvence UTF-8 se používá všude. Většina linuxových aplikací předpokládá, že textový vstup je kódován v kódování UTF-8. I když mnoho linuxových aplikací rozpozná a správně zpracuje kusovník, číslo ne, což vede k artefaktům v textu manipulovaných s těmito aplikacemi.
Proto:
- Pokud pracujete primárně s aplikacemi pro Windows a Windows PowerShellem, měli byste preferovat kódování, jako je UTF-8 s BOM nebo UTF-16.
- Pokud pracujete na různých platformách, měli byste preferovat UTF-8 s kusovníkem.
- Pokud pracujete hlavně v kontextech přidružených k Linuxu, měli byste preferovat UTF-8 bez kusovníku.
- Windows-1252 a latin-1 jsou v podstatě starší kódování, kterým byste se měli vyhnout, pokud je to možné. Některé starší aplikace pro Windows ale můžou záviset na nich.
- Je také vhodné poznamenat, že podepisování skriptů je závislé na kódování, což znamená, že změna kódování podepsaného skriptu bude vyžadovat rezignování.
Konfigurace VS Code
Výchozí kódování VS Code je UTF-8 bez kusovníku.
Pokud chcete nastavit kódování VS Code, přejděte do nastavení VS Code (Ctrl+) a nastavte "files.encoding"
nastavení:
"files.encoding": "utf8bom"
Mezi možné hodnoty patří:
utf8
: [UTF-8] bez kusovníkuutf8bom
: [UTF-8] s kusovníkemutf16le
: Little endian [UTF-16]utf16be
: Big endian [UTF-16]windows1252
: [Windows-1252]
V zobrazení grafického uživatelského rozhraní byste měli získat rozevírací seznam nebo jeho dokončení v zobrazení JSON.
Můžete také přidat následující kód pro automatické rozpoznávání, pokud je to možné:
"files.autoGuessEncoding": true
Pokud nechcete, aby tato nastavení ovlivnila všechny typy souborů, VS Code také umožňuje konfigurace jednotlivých jazyků. Nastavení specifické pro jazyk vytvoříte tak, že nastavení vložíte [<language-name>]
do pole. Příklad:
"[powershell]": {
"files.encoding": "utf8bom",
"files.autoGuessEncoding": true
}
Můžete také zvážit instalaci nástroje Gremlins tracker pro Visual Studio Code. Toto rozšíření odhalí určité znaky Unicode, které jsou snadno poškozené, protože jsou neviditelné nebo vypadají jako jiné normální znaky.
Konfigurace PowerShellu
Výchozí kódování PowerShellu se liší v závislosti na verzi:
- V PowerShellu 6+ je výchozí kódování UTF-8 bez BOM na všech platformách.
- Ve Windows PowerShellu je výchozí kódování obvykle Windows-1252, což je rozšíření latin-1 (označované také jako ISO 8859-1).
V PowerShellu 5 nebo novějším můžete najít výchozí kódování takto:
[psobject].Assembly.GetTypes() | Where-Object { $_.Name -eq 'ClrFacade'} |
ForEach-Object {
$_.GetMethod('GetDefaultEncoding', [System.Reflection.BindingFlags]'nonpublic,static').Invoke($null, @())
}
Následující skript se dá použít k určení kódování relace PowerShellu pro skript bez kusovníku.
$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
}
PowerShell je možné nakonfigurovat tak, aby používal dané kódování obecněji pomocí nastavení profilu. Podívejte se na následující články:
- @mklement0Odpověď na kódování PowerShellu v StackOverflow.
- @rkeithhillBlogový příspěvek o práci se vstupem UTF-8 bez BOM v PowerShellu
PowerShell není možné vynutit použití konkrétního kódování vstupu. PowerShell 5.1 a novější, který běží ve Windows s národním prostředím nastaveným na en-US, se ve výchozím nastavení nastaví na kódování Windows-1252, pokud neexistuje žádný kusovník. Jiná nastavení národního prostředí můžou používat jiné kódování. Pokud chcete zajistit interoperabilitu, je nejlepší uložit skripty ve formátu Unicode pomocí kusovníku.
Důležité
Jakékoli jiné nástroje, které máte, mohou být ovlivněny vašimi volbami kódování nebo překódováním skriptů do jiného kódování.
Existující skripty
Skripty, které už jsou v systému souborů, možná bude potřeba překódovat do nového zvoleného kódování. Na dolním panelu VS Code uvidíte popisek UTF-8. Kliknutím na něj otevřete panel akcí a vyberte Uložit s kódováním. Teď můžete vybrat nové kódování pro tento soubor. Úplné pokyny najdete v kódování VS Code.
Pokud potřebujete znovu zakódovat více souborů, můžete použít následující skript:
Get-ChildItem *.ps1 -Recurse | ForEach-Object {
$content = Get-Content -Path $_
Set-Content -Path $_.Fullname -Value $content -Encoding UTF8 -PassThru -Force
}
Integrované skriptovací prostředí PowerShellu (ISE)
Pokud také upravujete skripty pomocí prostředí PowerShell ISE, musíte tam synchronizovat nastavení kódování.
ISE by měl respektovat kusovník, ale k nastavení kódování je také možné použít reflexi. Mějte na paměti, že mezi spuštěními by to nebylo trvalé.
Software správy zdrojového kódu
Některé nástroje správy zdrojového kódu, jako je git, ignorují kódování; Git jen sleduje bajty. Jiné, například Azure DevOps nebo Mercurial, nemusí. Dokonce i některé nástroje založené na Gitu spoléhají na dekódování textu.
V takovém případě se ujistěte, že:
- Nakonfigurujte kódování textu ve správě zdrojového kódu tak, aby odpovídalo konfiguraci VS Code.
- Ujistěte se, že jsou všechny soubory v příslušném kódování vráceny se správou zdrojového kódu.
- Dávejte pozor na změny kódování přijaté prostřednictvím správy zdrojového kódu. Klíčové znaménko je rozdíl označující změny, ale tam, kde se zdá, že se nic nezměnilo (protože bajty mají, ale znaky nemají).
Prostředí spolupracovníků
Nad konfigurací správy zdrojového kódu se ujistěte, že vaši spolupracovníci na všech sdílených souborech nemají nastavení, která přepisují kódování tím, že překódují soubory PowerShellu.
Další programy
Jakýkoli jiný program, který čte nebo zapisuje skript PowerShellu, ho může překódovat.
Zde je několik příkladů:
- Pomocí schránky zkopírujete a vložíte skript. To je běžné ve scénářích, jako jsou:
- Kopírování skriptu do virtuálního počítače
- Kopírování skriptu z e-mailu nebo webové stránky
- Kopírování skriptu do nebo z dokumentu Microsoft Wordu nebo PowerPointu
- Další textové editory, například:
- Poznámkový blok
- vim
- Jakýkoli jiný editor skriptů PowerShellu
- Nástroje pro úpravy textu, například:
Get-Content
/Set-Content
/Out-File
- Operátory přesměrování PowerShellu, jako jsou
>
a>>
sed
/awk
- Programy pro přenos souborů, například:
- Webový prohlížeč při stahování skriptů
- Sdílená složka
Některé z těchto nástrojů se zabývají bajty místo textu, ale jiné nabízejí konfigurace kódování. V takových případech, kdy potřebujete nakonfigurovat kódování, musíte ho nastavit stejně jako kódování editoru, aby se zabránilo problémům.
Další prostředky pro kódování v PowerShellu
Existuje několik dalších užitečných příspěvků o kódování a konfiguraci kódování v PowerShellu, které stojí za přečtení:
- about_Character_Encoding
- @mklement0Souhrn kódování PowerShellu ve službě StackOverflow
- Předchozí problémy otevřené v prostředí VS Code-PowerShell pro problémy s kódováním:
- Klasický Joel on Software psát o Unicode
- Kódování v .NET Standard