Condividi tramite


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 ( ) o virgolette doppie a sinistra (")
  • 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, un trattino () appare come i 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 â&euro;"From $from â&euro;"To $recipient1 â&euro;"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 â&euro;".

Alcune sequenze di caratteri strane che potrebbero essere visualizzate includono:

  • â&euro;" anziché (un trattino)
  • â&euro;" invece di (una lineetta)
  • Ä2 invece di Ä
  • Â anziché   (uno spazio non separabile)
  • Ã&copy; 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:

  1. Quando gli script vengono modificati in VS Code, il contenuto viene inviato da VS Code all'estensione. Il Language Server Protocol impone che questo contenuto sia trasferito in UTF-8. Non è quindi possibile che l'estensione ottenga la codifica errata.
  2. 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.
  3. 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 utilizza la codifica UTF-8, ma usa il rilevamento del marchio d'ordine dei byte, o 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 marcatore di ordine dei byte (BOM). BOMs compaiono all'inizio del testo per indicare a un decodificatore quale codifica il testo stia utilizzando. Per le codifiche a più byte, il BOM indica anche l'endianità della codifica. I BOM sono progettati per essere byte che raramente si verificano nel testo che non è Unicode, consentendo un'ipotesi ragionevole che il testo sia Unicode quando è presente un BOM.

I BOM sono facoltativi e la loro adozione non è così comune nel mondo Linux perché una convenzione affidabile dell'UTF-8 è usata ovunque. La maggior parte delle applicazioni Linux presuppone che l'input di testo sia codificato in UTF-8. Anche se molte applicazioni Linux riconoscono e gestiscono correttamente un BOM, alcune no, 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, il che significa che una modifica della codifica in uno script firmato richiederà una nuova firma.

Configurazione di VS Code

La codifica predefinita di VS Code è UTF-8 senza BOM.

Per impostare la codifica di VS Code, vai alle impostazioni di VS Code (CTRL+,) e configura la relativa opzione "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 utilizzare il seguente script per determinare quale codifica la sessione di PowerShell deduce per uno script senza un Byte Order Mark (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
}

È possibile configurare PowerShell per usare una codifica specifica in genere usando le impostazioni del profilo. Vedere gli articoli seguenti:

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 che interagisce con gli script di PowerShell potrebbe essere influenzato dalle vostre scelte di codifica o ricodificare i vostri 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 la 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 *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 inseriti nel sistema di 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 in cui nulla sembra essere cambiato (perché i byte sono cambiati ma i caratteri no).

Ambienti dei collaboratori

Oltre alla configurazione del controllo del codice sorgente, assicurati che i collaboratori su qualsiasi file condiviso non abbiano impostazioni che rimpiazzano la tua codifica ricodificando i 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 di 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: