Informazioni sulla codifica dei file in VS Code e PowerShell
Quando si usa VS Code per creare e modificare script di PowerShell, è importante salvare i file usando il formato di codifica dei caratteri corretto.
Che cos'è la codifica dei file e perché è importante?
VS Code gestisce l'interfaccia tra un utente che immette stringhe di caratteri in un buffer e blocchi di lettura/scrittura di byte nel file system. Quando VS Code salva un file, usa una codifica di testo per decidere quali byte diventano ogni carattere. Per altre informazioni, vedere about_Character_Encoding.
Analogamente, quando PowerShell esegue uno script, deve convertire i byte in un file in caratteri per ricostruire il file in un programma PowerShell. Poiché VS Code scrive il file e PowerShell legge il file, è necessario usare lo stesso sistema di codifica. Questo processo di analisi di uno script di PowerShell va: byte ->caratteri ->token ->albero della sintassi astratta ->esecuzione.
Sia VS Code che PowerShell vengono installati con una configurazione di codifica predefinita appropriata. Tuttavia, la codifica predefinita usata da PowerShell è cambiata con la versione di PowerShell 6. Per assicurarsi di non avere problemi con PowerShell o l'estensione PowerShell in VS Code, è necessario configurare correttamente le impostazioni di VS Code e PowerShell.
Cause comuni dei problemi di codifica
I problemi di codifica si verificano quando la codifica di VS Code o il file di script non corrisponde alla codifica prevista di PowerShell. PowerShell non consente di determinare automaticamente la codifica dei file.
È più probabile che si verifichino problemi di codifica quando si usano caratteri non presenti nel set di caratteri ASCII a 7 bit . Per esempio:
- Caratteri non lettera estesi come em-dash (
—
), spazio non di interruzione ("
) - Caratteri latini accentati (
É
,ü
) - Caratteri non latini come cirillico (
Д
,Ц
) - Caratteri CJK (
本
,화
,が
)
I motivi comuni per cui si verificano i problemi di codifica sono:
- Le codifiche di VS Code e PowerShell non sono state modificate rispetto alle impostazioni predefinite. Per PowerShell 5.1 e versioni successive, la codifica predefinita è diversa da quella di VS Code.
- Un altro editor ha aperto e sovrascritto il file in una nuova codifica. Questo accade spesso con l'ISE.
- Il file viene archiviato nel controllo del codice sorgente in una codifica diversa da quella prevista da VS Code o PowerShell. Ciò può verificarsi quando i collaboratori usano editor con configurazioni di codifica diverse.
Come stabilire quando si verificano problemi di codifica
Spesso gli errori di codifica si presentano come errori di analisi negli script. Se si trovano sequenze di caratteri strane nello script, questo può essere il problema. Nell'esempio seguente viene visualizzato un trattino en-dash (–
) come caratteri â€"
:
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
Questo problema si verifica perché VS Code codifica il carattere –
in UTF-8 come byte 0xE2 0x80 0x93
. Quando questi byte vengono decodificati come Windows-1252, vengono interpretati come caratteri â€"
.
Alcune sequenze di caratteri strane che potrebbero essere visualizzate includono:
-
â€"
anziché–
(un trattino) -
â€"
invece di—
(un trattino em)) -
Ä2
invece diÄ
-
Â
anziché -
é
invece dié
Questo pratico riferimento elenca i modelli comuni che indicano un problema di codifica UTF-8/Windows-1252.
Interazione dell'estensione PowerShell in VS Code con le codifiche
L'estensione PowerShell interagisce con gli script in diversi modi:
- Quando gli script vengono modificati in VS Code, il contenuto viene inviato da VS Code all'estensione. Il
Language Server Protocol impone che il contenuto venga trasferito in UTF-8. Non è quindi possibile che l'estensione ottenga la codifica errata. - Quando gli script vengono eseguiti direttamente nella console integrata, vengono letti dal file direttamente da PowerShell. Se la codifica di PowerShell è diversa da quella di VS Code, è possibile che si verifichi un problema qui.
- Quando uno script aperto in VS Code fa riferimento a un altro script che non è aperto in VS Code, l'estensione esegue il fallback al caricamento del contenuto dello script dal file system. Per impostazione predefinita, l'estensione PowerShell usa la codifica UTF-8, ma usa byte order marko BOM per selezionare la codifica corretta.
Il problema si verifica quando si presuppone la codifica di formati senza BOM (ad esempio UTF-8 senza bom e Windows-1252). Per impostazione predefinita, l'estensione di PowerShell è UTF-8. L'estensione non può modificare le impostazioni di codifica di VS Code. Per altre informazioni, vedere problema #824.
Scelta della codifica corretta
Diversi sistemi e applicazioni possono usare codifiche diverse:
- In .NET Standard, sul Web e nel mondo Linux, UTF-8 è ora la codifica dominante.
- Molte applicazioni .NET Framework usano UTF-16. Per motivi cronologici, questo è talvolta denominato "Unicode", un termine che ora si riferisce a un'ampia standard che include sia UTF-8 che UTF-16.
- In Windows molte applicazioni native che precedono Unicode continuano a usare Windows-1252 per impostazione predefinita.
Le codifiche Unicode hanno anche il concetto di indicatore di ordine byte (BOM). Le macchine virtuali si verificano all'inizio del testo per indicare a un decodificatore la codifica del testo in uso. Per le codifiche a più byte, la distinta base indica anche endianità della codifica. Le macchine virtuali sono progettate per essere byte che raramente si verificano in testo non Unicode, consentendo un'ipotesi ragionevole che il testo sia Unicode quando è presente un BOM.
Le macchine virtuali sono facoltative e la loro adozione non è così diffusa nel mondo Linux perché viene usata ovunque una convenzione affidabile di UTF-8. La maggior parte delle applicazioni Linux presuppone che l'input di testo sia codificato in UTF-8. Anche se molte applicazioni Linux riconosceranno e gestiranno correttamente una distinta base, un numero non, causando artefatti nel testo manipolato con tali applicazioni.
pertanto:
- Se si lavora principalmente con applicazioni Windows e Windows PowerShell, è consigliabile preferire una codifica come UTF-8 con BOM o UTF-16.
- Se si lavora su più piattaforme, è consigliabile preferire UTF-8 con BOM.
- Se si lavora principalmente in contesti associati a Linux, è consigliabile preferire UTF-8 senza BOM.
- Windows-1252 e latin-1 sono essenzialmente codifiche legacy che è consigliabile evitare, se possibile. Tuttavia, alcune applicazioni Windows meno recenti possono dipendere da esse.
- Vale anche la pena notare che la firma dello script è dipendente dalla codifica, ovvero una modifica della codifica in uno script firmato richiederà la riassegnazione.
Configurazione di VS Code
La codifica predefinita di VS Code è UTF-8 senza BOM.
Per impostare di codifica di VS Code, passare alle impostazioni di VS Code (CTRL+,) e impostare l'impostazione "files.encoding"
:
"files.encoding": "utf8bom"
Alcuni valori possibili sono:
-
utf8
: [UTF-8] senza BOM -
utf8bom
: [UTF-8] con BOM -
utf16le
: Little endian [UTF-16] -
utf16be
: Big endian [UTF-16] -
windows1252
: [Windows-1252]
È necessario ottenere un elenco a discesa nella visualizzazione GUI o i completamenti per questo nella visualizzazione JSON.
È anche possibile aggiungere quanto segue alla codifica di rilevamento automatico, quando possibile:
"files.autoGuessEncoding": true
Se non si vuole che queste impostazioni influiscano su tutti i tipi di file, VS Code consente anche configurazioni per linguaggio. Creare un'impostazione specifica della lingua inserendo le impostazioni in un campo [<language-name>]
. Per esempio:
"[powershell]": {
"files.encoding": "utf8bom",
"files.autoGuessEncoding": true
}
È anche possibile prendere in considerazione l'installazione del gremlins tracker per Visual Studio Code. Questa estensione rivela alcuni caratteri Unicode facilmente danneggiati perché sono invisibili o simili ad altri caratteri normali.
Configurazione di PowerShell
La codifica predefinita di PowerShell varia a seconda della versione:
- In PowerShell 6+, la codifica predefinita è UTF-8 senza bom su tutte le piattaforme.
- In Windows PowerShell la codifica predefinita è in genere Windows-1252, che è un'estensione di latin-1 (nota anche come ISO 8859-1).
In PowerShell 5+ è possibile trovare la codifica predefinita con questo:
[psobject].Assembly.GetTypes() | Where-Object { $_.Name -eq 'ClrFacade'} |
ForEach-Object {
$_.GetMethod('GetDefaultEncoding', [System.Reflection.BindingFlags]'nonpublic,static').Invoke($null, @())
}
È possibile usare lo script seguente per determinare la codifica della sessione di PowerShell inferta per uno script senza distinta base.
$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
}
È possibile configurare PowerShell per usare una codifica specifica in genere usando le impostazioni del profilo. Vedere gli articoli seguenti:
- @mklement0risposta sulla codifica di PowerShell in Stack Overflow.
- @rkeithhillpost di blog di sull'uso dell'input UTF-8 senza boma in PowerShell.
Non è possibile forzare PowerShell a usare una codifica di input specifica. PowerShell 5.1 e versioni successive, in esecuzione in Windows con le impostazioni locali impostate su en-US, per impostazione predefinita viene impostata la codifica Windows-1252 quando non è presente un BOM. Altre impostazioni locali possono usare una codifica diversa. Per garantire l'interoperabilità, è consigliabile salvare gli script in un formato Unicode con un BOM.
Importante
Qualsiasi altro strumento disponibile per il tocco degli script di PowerShell può essere influenzato dalle scelte di codifica o dalla ridecrittura degli script in un'altra codifica.
Script esistenti
Gli script già presenti nel file system potrebbero dover essere codificati nuovamente nella nuova codifica scelta. Nella barra inferiore di VS Code verrà visualizzata l'etichetta UTF-8. Fare clic su di esso per aprire la barra delle azioni e selezionare Salva con codifica. È ora possibile selezionare una nuova codifica per il file. Per istruzioni complete, vedere di codifica di VS Code.
Se è necessario codificare nuovamente più file, è possibile usare lo script seguente:
Get-ChildItem *.ps1 -Recurse | ForEach-Object {
$content = Get-Content -Path $_
Set-Content -Path $_.Fullname -Value $content -Encoding UTF8 -PassThru -Force
}
Ambiente di scripting integrato di PowerShell (ISE)
Se si modificano anche gli script usando PowerShell ISE, è necessario sincronizzare le impostazioni di codifica in questa posizione.
L'ISE deve rispettare un BOM, ma è anche possibile usare la reflection per impostare la codifica. Si noti che questo non verrà salvato in modo permanente tra le startup.
Software di controllo del codice sorgente
Alcuni strumenti di controllo del codice sorgente, ad esempio Git, ignorano le codifiche; Git tiene traccia dei byte. Altri, ad esempio Azure DevOps o Mercurial, potrebbero non essere disponibili. Anche alcuni strumenti basati su Git si basano sulla decodifica del testo.
In questo caso, assicurarsi di:
- Configurare la codifica del testo nel controllo del codice sorgente in modo che corrisponda alla configurazione di VS Code.
- Verificare che tutti i file siano controllati nel controllo del codice sorgente nella codifica pertinente.
- Fare attenzione alle modifiche apportate alla codifica ricevuta tramite il controllo del codice sorgente. Un segno chiave di questo è un diff che indica le modifiche, ma dove nulla sembra essere cambiato (perché i byte hanno ma i caratteri non hanno).
Ambienti dei collaboratori
Oltre alla configurazione del controllo del codice sorgente, assicurarsi che i collaboratori in tutti i file condivisi non dispongano di impostazioni che eseguono l'override della codifica eseguendo nuovamente la codifica dei file di PowerShell.
Altri programmi
Qualsiasi altro programma che legge o scrive uno script di PowerShell può codificarlo nuovamente.
Ecco alcuni esempi:
- Uso degli Appunti per copiare e incollare uno script. Questo è comune negli scenari come:
- Copia di uno script in una macchina virtuale
- Copia di uno script da un messaggio di posta elettronica o una pagina Web
- Copia di uno script all'interno o all'esterno di un documento di Microsoft Word o PowerPoint
- Altri editor di testo, ad esempio:
- Bloc-notes
- vigore
- Qualsiasi altro editor di script di PowerShell
- Utilità di modifica del testo, ad esempio:
Get-Content
/Set-Content
/Out-File
- Operatori di reindirizzamento di PowerShell come
>
e>>
sed
/awk
- Programmi di trasferimento file, ad esempio:
- Un Web browser, quando si scaricano script
- Una condivisione file
Alcuni di questi strumenti gestiscono byte anziché testo, ma altri offrono configurazioni di codifica. In questi casi in cui è necessario configurare una codifica, è necessario renderla uguale alla codifica dell'editor per evitare problemi.
Altre risorse sulla codifica in PowerShell
Esistono alcuni altri post interessanti sulla codifica e sulla configurazione della codifica in PowerShell che vale la pena leggere:
- about_Character_Encoding
- Riepilogo @mklement0della codifica di PowerShell in Stack Overflow
- Problemi precedenti aperti in Vs Code-PowerShell per problemi di codifica:
- Il classico Joel on Software scrivere su Unicode
- codifica in .NET Standard