Descripción de la codificación de archivos en VS Code y PowerShell
Al usar VS Code para crear y editar scripts de PowerShell, es importante que los archivos se guarden con el formato de codificación de caracteres correcto.
¿Qué es la codificación de archivos y por qué es importante?
VS Code administra la interfaz entre una persona que escribe cadenas de caracteres en un búfer y bloques de lectura y escritura de bytes en el sistema de archivos. Cuando VS Code guarda un archivo, usa una codificación de texto para decidir qué bytes se convierte cada carácter. Para obtener más información, vea about_Character_Encoding.
De forma similar, cuando PowerShell ejecuta un script, debe convertir los bytes de un archivo en caracteres para reconstruir el archivo en un programa de PowerShell. Dado que VS Code escribe el archivo y PowerShell lee el archivo, deben usar el mismo sistema de codificación. Este proceso de análisis de un script de PowerShell va: bytes ->caracteres ->tokens ->árbol de sintaxis abstracta ->ejecución.
VS Code y PowerShell se instalan con una configuración de codificación predeterminada razonable. Sin embargo, la codificación predeterminada que usa PowerShell ha cambiado con la versión de PowerShell 6. Para asegurarse de que no tiene problemas con PowerShell o la extensión de PowerShell en VS Code, debe configurar los valores de VS Code y PowerShell correctamente.
Causas comunes de problemas de codificación
Los problemas de codificación se producen cuando la codificación de VS Code o el archivo de script no coincide con la codificación esperada de PowerShell. No hay ninguna manera de que PowerShell determine automáticamente la codificación de archivos.
Es más probable que tenga problemas de codificación cuando use caracteres que no están en el juego de caracteres ASCII de 7 bits . Por ejemplo:
- Caracteres no de letra extendidos como em-dash (
—
), espacio sin separación ("
) - Caracteres latinos acentuados (
É
,ü
) - Caracteres no latinos como Cirílico (
Д
,Ц
) - Caracteres CJK (
本
,화
,が
)
Las razones comunes para los problemas de codificación son:
- Las codificaciones de VS Code y PowerShell no se han cambiado de sus valores predeterminados. Para PowerShell 5.1 y versiones posteriores, la codificación predeterminada es diferente de la de VS Code.
- Otro editor ha abierto y sobrescribido el archivo en una nueva codificación. Esto suele ocurrir con el ISE.
- El archivo se protege en el control de código fuente en una codificación diferente de lo que VS Code o PowerShell espera. Esto puede ocurrir cuando los colaboradores usan editores con distintas configuraciones de codificación.
Cómo saber cuándo tiene problemas de codificación
A menudo, los errores de codificación se presentan como errores de análisis en scripts. Si encuentra secuencias de caracteres extrañas en el script, puede ser el problema. En el ejemplo siguiente, aparece un guión en -dash (–
) como los caracteres â€"
:
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
Este problema se produce porque VS Code codifica el carácter –
en UTF-8 como bytes 0xE2 0x80 0x93
. Cuando estos bytes se descodifican como Windows-1252, se interpretan como los caracteres â€"
.
Algunas secuencias de caracteres extrañas que podría ver incluyen:
-
â€"
en lugar de–
(un guión) -
â€"
en lugar de—
(un guión em) -
Ä2
en lugar deÄ
-
Â
en lugar de -
é
en lugar deé
Esta práctica referencia enumera los patrones comunes que indican un problema de codificación UTF-8/Windows-1252.
Cómo interactúa la extensión de PowerShell en VS Code con codificaciones
La extensión de PowerShell interactúa con scripts de varias maneras:
- Cuando los scripts se editan en VS Code, VS Code envía el contenido a la extensión. El Protocolo de servidor de lenguaje exige que este contenido se transfiera en UTF-8. Por lo tanto, no es posible que la extensión obtenga la codificación incorrecta.
- Cuando los scripts se ejecutan directamente en la consola integrada, PowerShell los lee directamente desde el archivo. Si la codificación de PowerShell difiere de las de VS Code, algo puede ir mal aquí.
- Cuando un script que está abierto en VS Code hace referencia a otro script que no está abierto en VS Code, la extensión vuelve a cargar el contenido del script desde el sistema de archivos. La extensión de PowerShell tiene como valor predeterminado la codificación UTF-8, pero usa marca de orden de bytes, o BOM, detección para seleccionar la codificación correcta.
El problema se produce al asumir la codificación de formatos sin BOM (como UTF-8 sin BOM y Windows-1252). La extensión de PowerShell tiene como valor predeterminado UTF-8. La extensión no puede cambiar la configuración de codificación de VS Code. Para obtener más información, vea problema n.º 824.
Elección de la codificación correcta
Diferentes sistemas y aplicaciones pueden usar codificaciones diferentes:
- En .NET Standard, en la web y en el mundo de Linux, UTF-8 es ahora la codificación dominante.
- Muchas aplicaciones de .NET Framework usan UTF-16. Por razones históricas, esto a veces se denomina "Unicode", un término que ahora hace referencia a un amplio estándar que incluye tanto UTF-8 como UTF-16.
- En Windows, muchas aplicaciones nativas que predate Unicode siguen usando Windows-1252 de forma predeterminada.
Las codificaciones Unicode también tienen el concepto de una marca de orden de bytes (BOM). Las BOM se producen al principio del texto para indicar a un descodificador que codifica el texto está usando. En el caso de las codificaciones de varios bytes, la lista de materiales también indica endianidad de la codificación. Las listas de materiales están diseñadas para ser bytes que rara vez se producen en texto no Unicode, lo que permite una estimación razonable de que el texto es Unicode cuando hay una boM presente.
Las listas de materiales son opcionales y su adopción no es tan popular en el mundo de Linux porque se usa una convención confiable de UTF-8 en todas partes. La mayoría de las aplicaciones Linux suponen que la entrada de texto está codificada en UTF-8. Aunque muchas aplicaciones de Linux reconocerán y controlarán correctamente una lista de materiales, un número no, lo que conduce a artefactos en texto manipulado con esas aplicaciones.
Por lo tanto,:
- Si trabaja principalmente con aplicaciones de Windows y Windows PowerShell, debe preferir una codificación como UTF-8 con BOM o UTF-16.
- Si trabaja entre plataformas, debe preferir UTF-8 con BOM.
- Si trabaja principalmente en contextos asociados a Linux, debe preferir UTF-8 sin BOM.
- Windows-1252 y latin-1 son básicamente codificaciones heredadas que debe evitar si es posible. Sin embargo, algunas aplicaciones de Windows anteriores pueden depender de ellas.
- También merece la pena tener en cuenta que la firma de scripts es dependiente de la codificación, lo que significa que un cambio de codificación en un script firmado requerirá la renuncia.
Configuración de VS Code
La codificación predeterminada de VS Code es UTF-8 sin BOM.
Para establecer
"files.encoding": "utf8bom"
Algunos valores posibles son:
-
utf8
: [UTF-8] sin BOM -
utf8bom
: [UTF-8] con BOM -
utf16le
: Little endian [UTF-16] -
utf16be
: Big endian [UTF-16] -
windows1252
: [Windows-1252]
Debería obtener una lista desplegable para esto en la vista gui o finalizaciones para ella en la vista JSON.
También puede agregar lo siguiente para la codificación de detección automática siempre que sea posible:
"files.autoGuessEncoding": true
Si no desea que esta configuración afecte a todos los tipos de archivos, VS Code también permite configuraciones por lenguaje. Cree una configuración específica del idioma colocando la configuración en un campo [<language-name>]
. Por ejemplo:
"[powershell]": {
"files.encoding": "utf8bom",
"files.autoGuessEncoding": true
}
También puede considerar la posibilidad de instalar el de seguimiento de Gremlins de
Configuración de PowerShell
La codificación predeterminada de PowerShell varía en función de la versión:
- En PowerShell 6 y versiones posteriores, la codificación predeterminada es UTF-8 sin BOM en todas las plataformas.
- En Windows PowerShell, la codificación predeterminada suele ser Windows-1252, que es una extensión de latin-1 (también conocida como ISO 8859-1).
En PowerShell 5+ puede encontrar la codificación predeterminada con esto:
[psobject].Assembly.GetTypes() | Where-Object { $_.Name -eq 'ClrFacade'} |
ForEach-Object {
$_.GetMethod('GetDefaultEncoding', [System.Reflection.BindingFlags]'nonpublic,static').Invoke($null, @())
}
El siguiente script de se puede usar para determinar qué codifica la sesión de PowerShell deduce para un script sin una 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
}
Es posible configurar PowerShell para que use una codificación determinada con mayor carácter general mediante la configuración del perfil. Consulte los artículos siguientes:
- @mklement0respuesta sobre la codificación de PowerShell en Stack Overflow.
- @rkeithhillentrada de blog de sobre cómo tratar la entrada UTF-8 sin BOM en PowerShell.
No es posible forzar a PowerShell a usar una codificación de entrada específica. PowerShell 5.1 y versiones posteriores, que se ejecutan en Windows con la configuración regional establecida en en-US, el valor predeterminado es la codificación de Windows-1252 cuando no hay ninguna boM. Otras configuraciones de configuración regional pueden usar una codificación diferente. Para garantizar la interoperabilidad, es mejor guardar scripts en un formato Unicode con una lista de materiales.
Importante
Cualquier otra herramienta que tenga que tocar scripts de PowerShell puede verse afectado por las opciones de codificación o volver a codificar los scripts en otra codificación.
Scripts existentes
Es posible que los scripts que ya estén en el sistema de archivos deban volver a codificarse en la nueva codificación elegida. En la barra inferior de VS Code, verá la etiqueta UTF-8. Haga clic en ella para abrir la barra de acciones y seleccione Guardar con codificación. Ahora puede elegir una nueva codificación para ese archivo. Consulte de codificación de VS Code para obtener instrucciones completas.
Si necesita volver a codificar varios archivos, puede usar el siguiente script:
Get-ChildItem *.ps1 -Recurse | ForEach-Object {
$content = Get-Content -Path $_
Set-Content -Path $_.Fullname -Value $content -Encoding UTF8 -PassThru -Force
}
El entorno de scripting integrado (ISE) de PowerShell
Si también edita scripts mediante PowerShell ISE, debe sincronizar la configuración de codificación allí.
El ISE debe respetar una lista de materiales, pero también es posible usar la reflexión para establecer la codificación. Tenga en cuenta que esto no se conservaría entre las startups.
Software de control de código fuente
Algunas herramientas de control de código fuente, como Git, omiten las codificaciones; Git solo realiza un seguimiento de los bytes. Otros, como Azure DevOps o Mercurial, pueden no. Incluso algunas herramientas basadas en Git se basan en la descodificación de texto.
Cuando este es el caso, asegúrese de que:
- Configure la codificación de texto en el control de código fuente para que coincida con la configuración de VS Code.
- Asegúrese de que todos los archivos están protegidos en el control de código fuente en la codificación pertinente.
- Tenga cuidado con los cambios en la codificación recibida a través del control de código fuente. Un signo clave de esto es una diferencia que indica los cambios, pero donde no parece haber cambiado nada (porque los bytes tienen pero no tienen caracteres).
Entornos de colaboradores
Además de configurar el control de código fuente, asegúrese de que los colaboradores de los archivos que comparta no tengan la configuración que invalide la codificación mediante la recodificación de archivos de PowerShell.
Otros programas
Cualquier otro programa que lea o escriba un script de PowerShell puede volver a codificarlo.
Algunos ejemplos son:
- Usar el Portapapeles para copiar y pegar un script. Esto es común en escenarios como:
- Copia de un script en una máquina virtual
- Copiar un script fuera de un correo electrónico o una página web
- Copiar un script dentro o fuera de un documento de Microsoft Word o PowerPoint
- Otros editores de texto, como:
- Bloc
- Vim
- Cualquier otro editor de scripts de PowerShell
- Utilidades de edición de texto, como:
Get-Content
/Set-Content
/Out-File
- Operadores de redirección de PowerShell como
>
y>>
sed
/awk
- Programas de transferencia de archivos, como:
- Un explorador web, al descargar scripts
- Un recurso compartido de archivos
Algunas de estas herramientas tratan en bytes en lugar de texto, pero otras ofrecen configuraciones de codificación. En aquellos casos en los que necesite configurar una codificación, debe hacerlo igual que la codificación del editor para evitar problemas.
Otros recursos sobre la codificación en PowerShell
Hay algunas otras entradas interesantes sobre la codificación y configuración de la codificación en PowerShell que merece la pena leer:
- about_Character_Encoding
- @mklement0resumen de codificación de PowerShell en Stack Overflow
- Problemas anteriores abiertos en VS Code-PowerShell para problemas de codificación:
- El clásico Joel en Software escribir sobre Unicode
- codificación en .NET Standard