Descripción de la codificación de archivo en VS Code y PowerShellUnderstanding file encoding in VS Code and 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.When using VS Code to create and edit PowerShell scripts, it is important that your files are saved using the correct character encoding format.

¿Qué es la codificación de archivo y por qué es importante?What is file encoding and why is it important?

VS Code administra la interfaz entre una entrada manual de cadenas de caracteres en un búfer y la lectura/escritura de bloques de bytes en el sistema de archivos.VS Code manages the interface between a human entering strings of characters into a buffer and reading/writing blocks of bytes to the filesystem. Cuando VS Code guarda un archivo, usa una codificación de texto para decidir en qué bytes se convierte cada carácter.When VS Code saves a file, it uses a text encoding to decide what bytes each character becomes. Para obtener más información, vea Acerca de la codificación de caracteres.For more information, see about_Character_Encoding.

De forma similar, cuando PowerShell ejecuta un script debe convertir los bytes de un archivo a caracteres para reconstruir el archivo en un programa de PowerShell.Similarly, when PowerShell runs a script it must convert the bytes in a file to characters to reconstruct the file into a PowerShell program. Dado que VS Code escribe el archivo y PowerShell lee el archivo, deben usar el mismo sistema de codificación.Since VS Code writes the file and PowerShell reads the file, they need to use the same encoding system. Este proceso de análisis de un script de PowerShell es: bytes -> caracteres -> tokens -> árbol de sintaxis abstracta -> ejecución.This process of parsing a PowerShell script goes: bytes -> characters -> tokens -> abstract syntax tree -> execution.

VS Code y PowerShell se instalan con una configuración de codificación predeterminada sensible.Both VS Code and PowerShell are installed with a sensible default encoding configuration. Sin embargo, la codificación predeterminada usada por PowerShell ha cambiado con la publicación de PowerShell Core (versión 6.x).However, the default encoding used by PowerShell has changed with the release of PowerShell Core (v6.x). Para garantizar que no tiene problemas con el uso de PowerShell o la extensión de PowerShell en VS Code, debe configurar sus opciones de VS Code y PowerShell correctamente.To ensure you have no problems using PowerShell or the PowerShell extension in VS Code, you need to configure your VS Code and PowerShell settings properly.

Causas comunes de problemas de codificaciónCommon causes of encoding issues

Se producen problemas de codificación cuando la codificación de VS Code o el archivo de script no coincide con la codificación esperada de PowerShell.Encoding problems occur when the encoding of VS Code or your script file does not match the expected encoding of PowerShell. No hay ninguna forma de que PowerShell determine automáticamente la codificación del archivo.There is no way for PowerShell to automatically determine the file encoding.

Es más probable tener problemas de codificación cuando se usan caracteres que no están en el juego de caracteres ASCII de 7 bits.You're more likely to have encoding problems when you're using characters not in the 7-bit ASCII character set. Por ejemplo:For example:

  • Caracteres que no son letras extendidos, como guion largo (), espacio de no separación ( ) o comilla doble izquierda (")Extended non-letter characters like em-dash (), non-breaking space ( ) or left double quotation mark (")
  • Caracteres latinos acentuados (É, ü)Accented latin characters (É, ü)
  • Caracteres no latinos; por ejemplo, cirílico (Д, Ц)Non-latin characters like Cyrillic (Д, Ц)
  • Caracteres de CJK (, , )CJK characters (, , )

Algunas causas comunes de problemas de codificación son las siguientes:Common reasons for encoding issues are:

  • Las codificaciones de VS Code y PowerShell no han cambiado respecto a sus valores predeterminados.The encodings of VS Code and PowerShell have not been changed from their defaults. Para PowerShell 5.1 y versiones posteriores, el valor predeterminado de codificación es diferente del de VS Code.For PowerShell 5.1 and below, the default encoding is different from VS Code's.
  • Otro editor ha abierto y sobrescrito el archivo en una nueva codificación.Another editor has opened and overwritten the file in a new encoding. Esto suele ocurrir con el ISE.This often happens with the ISE.
  • El archivo se incorpora al control de código fuente en una codificación distinta a la que VS Code o PowerShell espera.The file is checked into source control in an encoding that is different from what VS Code or PowerShell expects. Esto puede ocurrir cuando los colaboradores usan editores con distintas configuraciones de codificación.This can happen when collaborators use editors with different encoding configurations.

Procedimiento para saber si tiene problemas de codificaciónHow to tell when you have encoding issues

Los errores de codificación, a menudo, se presentan como errores de análisis en los scripts.Often encoding errors present themselves as parse errors in scripts. Si encuentra secuencias de caracteres extraños en su script, éste puede ser el problema.If you find strange character sequences in your script, this can be the problem. En el ejemplo siguiente, un guión corto () aparece como los caracteres â€":In the example below, an en-dash () appears as the characters â€":

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

Este problema se produce porque VS Code codifica el carácter en UTF-8 como los bytes 0xE2 0x80 0x93.This problem occurs because VS Code encodes the character in UTF-8 as the bytes 0xE2 0x80 0x93. Cuando estos bytes se descodifican como Windows-1252, se interpretan como los caracteres â&euro;".When these bytes are decoded as Windows-1252, they are interpreted as the characters â&euro;".

Entre algunas secuencias de caracteres extraños que podría ver se incluyen:Some strange character sequences that you might see include:

  • â&euro;" en lugar de â&euro;" instead of
  • â&euro;" en lugar de â&euro;" instead of
  • Ä2 en lugar de ÄÄ2 instead of Ä
  • Â en lugar de (un espacio de no separación)Â instead of (a non-breaking space)
  • Ã&copy; en lugar de éÃ&copy; instead of é

Esta referencia práctica detalla los patrones comunes que indican un problema de codificación UTF-8/Windows-1252.This handy reference lists the common patterns that indicate a UTF-8/Windows-1252 encoding problem.

De qué forma la extensión de PowerShell en VS Code interactúa con las codificacionesHow the PowerShell extension in VS Code interacts with encodings

La extensión de PowerShell interactúa con los scripts de varias maneras:The PowerShell extension interacts with scripts in a number of ways:

  1. Cuando los scripts se editan en VS Code, el contenido lo envía VS Code a la extensión.When scripts are edited in VS Code, the contents are sent by VS Code to the extension. El protocolo de servidor de lenguaje obliga a que este contenido se transfiera en UTF-8.The Language Server Protocol mandates that this content is transferred in UTF-8. Por lo tanto, no es posible que la extensión obtenga la codificación incorrecta.Therefore, it is not possible for the extension to get the wrong encoding.
  2. Cuando los scripts se ejecutan directamente en la consola integrada, se leen desde el archivo de PowerShell directamente.When scripts are executed directly in the Integrated Console, they're read from the file by PowerShell directly. Si la codificación de PowerShell difiere de la de VS Code, es posible que algo no funcione bien.If PowerShell's encoding differs from VS Code's, something can go wrong here.
  3. Cuando un script que está abierto en VS Code hace referencia a otro script que no está abierto en VS Code, la extensión pasa de nuevo a cargar el contenido del script desde el sistema de archivos.When a script that is open in VS Code references another script that is not open in VS Code, the extension falls back to loading that script's content from the file system. La extensión de PowerShell tiene como valor predeterminado la codificación UTF-8, pero usa la detección de marca BOM para seleccionar la codificación correcta.The PowerShell extension defaults to UTF-8 encoding, but uses byte-order mark, or BOM, detection to select the correct encoding.

El problema se produce cuando se asume la codificación de formatos sin BOM (como UTF-8 sin BOM y Windows-1252).The problem occurs when assuming the encoding of BOM-less formats (like UTF-8 with no BOM and Windows-1252). La extensión de PowerShell tiene como valor predeterminado UTF-8.The PowerShell extension defaults to UTF-8. La extensión no puede cambiar la configuración de codificación de VS Code.The extension cannot change VS Code's encoding settings. Para obtener más información, vea el problema #824.For more information, see issue #824.

Elección de la codificación correctaChoosing the right encoding

Las aplicaciones y los sistemas distintos pueden utilizar codificaciones diferentes:Different systems and applications can use different encodings:

  • En .NET Standard, en la web y en el entorno Linux, UTF-8 es ahora la codificación dominante.In .NET Standard, on the web, and in the Linux world, UTF-8 is now the dominant encoding.
  • Muchas aplicaciones de .NET Framework usan UTF-16.Many .NET Framework applications use UTF-16. Por motivos históricos, a veces recibe la denominación de "Unicode", un término que ahora hace referencia a un amplio estándar que incluye tanto UTF-8 como UTF-16.For historical reasons, this is sometimes called "Unicode", a term that now refers to a broad standard that includes both UTF-8 and UTF-16.
  • En Windows, muchas aplicaciones nativas anteriores a Unicode siguen usando Windows-1252 de forma predeterminada.On Windows, many native applications that predate Unicode continue to use Windows-1252 by default.

Las codificaciones Unicode también tienen el concepto de una marca BOM.Unicode encodings also have the concept of a byte-order mark (BOM). Las BOM se producen al principio del texto para indicar a un descodificador la codificación que está usando el texto.BOMs occur at the beginning of text to tell a decoder which encoding the text is using. Para las codificaciones multibyte, la BOM también indica la marca endianness de la codificación.For multi-byte encodings, the BOM also indicates endianness of the encoding. Las BOM están diseñadas para ser bytes que rara vez se producen en texto no Unicode, permitiendo una estimación razonable de que el texto es Unicode cuando hay una BOM.BOMs are designed to be bytes that rarely occur in non-Unicode text, allowing a reasonable guess that text is Unicode when a BOM is present.

Las BOM son opcionales y su adopción no es tan popular en los entornos Linux, porque se utiliza de forma generalizada una convención dependiente de UTF-8.BOMs are optional and their adoption isn't as popular in the Linux world because a dependable convention of UTF-8 is used everywhere. La mayoría de las aplicaciones Linux dan por supuesto que la entrada de texto está codificada en UTF-8.Most Linux applications presume that text input is encoded in UTF-8. Si bien muchas aplicaciones Linux reconocen y tratan correctamente una BOM, algunas no lo hacen y esto provoca anomalías en el texto manipulado con esas aplicaciones.While many Linux applications will recognize and correctly handle a BOM, a number do not, leading to artifacts in text manipulated with those applications.

Por lo tanto :Therefore :

  • Si trabaja principalmente con aplicaciones Windows y Windows PowerShell, es preferible una codificación como UTF-8 con BOM o UTF-16.If you work primarily with Windows applications and Windows PowerShell, you should prefer an encoding like UTF-8 with BOM or UTF-16.
  • Si trabaja en varias plataformas, es preferible UTF-8 con BOM.If you work across platforms, you should prefer UTF-8 with BOM.
  • Si trabaja principalmente en contextos asociados a Linux, es preferible UTF-8 sin BOM.If you work mainly in Linux-associated contexts, you should prefer UTF-8 without BOM.
  • Windows-1252 y Latín-1 son básicamente codificaciones heredadas que deben evitarse en la medida de lo posible.Windows-1252 and latin-1 are essentially legacy encodings that you should avoid if possible. Sin embargo, algunas aplicaciones más antiguas de Windows pueden dependen de ellas.However, some older Windows applications may depend on them.
  • También merece la pena mencionar que la firma de scripts depende de la codificación, lo cual significa que un tras cambio de codificación en un script firmado será necesario volver a firmar.It's also worth noting that script signing is encoding-dependent, meaning a change of encoding on a signed script will require resigning.

Configuración de VS CodeConfiguring VS Code

La codificación predeterminada de VS Code es UTF-8 sin BOM.VS Code's default encoding is UTF-8 without BOM.

Para establecer la codificación de VS Code, vaya a la configuración de VS Code (Ctrl+,) y establezca la configuración de "files.encoding":To set VS Code's encoding, go to the VS Code settings (Ctrl+,) and set the "files.encoding" setting:

"files.encoding": "utf8bom"

Algunos valores posibles son:Some possible values are:

Debe obtener una lista desplegable para esto en la vista de la interfaz gráfica de usuario, o los resultados de ello en la vista de JSON.You should get a dropdown for this in the GUI view, or completions for it in the JSON view.

También puede agregar lo siguiente para detectar automáticamente la codificación, cuando sea posible:You can also add the following to autodetect encoding when possible:

"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.If you don't want these settings to affect all files types, VS Code also allows per-language configurations. Cree un ajuste específico del lenguaje colocando los ajustes en un campo [<language-name>].Create a language-specific setting by putting settings in a [<language-name>] field. Por ejemplo:For example:

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

También puede considerar la instalación del rastreador de Gremlins para Visual Studio Code.You may also want to consider installing the Gremlins tracker for Visual Studio Code. Esta extensión revela ciertos caracteres Unicode que se dañan fácilmente porque son invisibles o tienen un aspecto similar al de otros caracteres normales.This extension reveals certain Unicode characters that easily corrupted because they are invisible or look like other normal characters.

Configuración de PowerShellConfiguring PowerShell

La codificación predeterminada de PowerShell varía en función de la versión:PowerShell's default encoding varies depending on version:

  • En PowerShell 6 +, la codificación predeterminada es UTF-8 sin BOM en todas las plataformas.In PowerShell 6+, the default encoding is UTF-8 without BOM on all platforms.
  • En Windows PowerShell, la codificación predeterminada es normalmente Windows 1252, una extensión de latin-1, también conocida como ISO 8859-1.In Windows PowerShell, the default encoding is usually Windows-1252, an extension of latin-1, also known as ISO 8859-1.

En PowerShell 5+ puede encontrar la codificación predeterminada con esto:In PowerShell 5+ you can find your default encoding with this:

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

El siguiente script puede usarse para determinar la codificación que la sesión de PowerShell infiere para un script sin una BOM.The following script can be used to determine what encoding your PowerShell session infers for a script without a 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, de forma más general mediante la configuración del perfil.It's possible to configure PowerShell to use a given encoding more generally using profile settings. Vea los artículos siguientes:See the following articles:

No es posible obligar a PowerShell a usar una codificación de entrada específica.It's not possible to force PowerShell to use a specific input encoding. PowerShell 5.1 y versiones anteriores, que se ejecutan en Windows con la configuración regional establecida en en-US, tienen como de forma predeterminada la codificación Windows-1252 cuando no hay ninguna marca BOM.PowerShell 5.1 and below, running on Windows with the locale set to en-US, defaults to Windows-1252 encoding when there's no BOM. Otros ajustes de configuración regional pueden usar una codificación diferente.Other locale settings may use a different encoding. Para garantizar la interoperabilidad, es mejor guardar los scripts en un formato Unicode con una BOM.To ensure interoperability, it's best to save scripts in a Unicode format with a BOM.

Importante

Cualquier otra herramienta que tenga y entre en contacto con scripts de PowerShell puede verse afectada por sus opciones de codificación o puede volver a codificar los scripts a otra codificación.Any other tools you have that touch PowerShell scripts may be affected by your encoding choices or re-encode your scripts to another encoding.

Scripts existentesExisting scripts

Es posible que los scripts que ya se encuentran en el sistema de archivos deban volver a codificarse a la nueva codificación elegida.Scripts already on the file system may need to be re-encoded to your new chosen encoding. En la barra inferior de VS Code, verá la etiqueta UTF-8.In the bottom bar of VS Code, you'll see the label UTF-8. Haga clic en ella para abrir la barra de acciones y seleccione Guardar con codificación.Click it to open the action bar and select Save with encoding. Ahora puede elegir una codificación de nueva para ese archivo.You can now pick a new encoding for that file. Vea la información sobre la codificación de VS Code para obtener instrucciones completas.See VS Code's encoding for full instructions.

Si necesita volver a codificar varios archivos, puede usar el siguiente script:If you need to re-encode multiple files, you can use the following 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 PowerShellThe PowerShell Integrated Scripting Environment (ISE)

Si también edita scripts con PowerShell ISE, deberá sincronizar la configuración de codificación allí.If you also edit scripts using the PowerShell ISE, you need to synchronize your encoding settings there.

El ISE debe respetar una BOM, pero también es posible usar el reflejo para establecer la codificación.The ISE should honor a BOM, but it's also possible to use reflection to set the encoding. Tenga en cuenta que esto no se mantiene entre los inicios.Note that this wouldn't be persisted between startups.

Software de control de código fuenteSource control software

Algunas herramientas de control de código fuente, como GIT, ignoran las codificaciones; GIT simplemente realiza un seguimiento de los bytes.Some source control tools, such as git, ignore encodings; git just tracks the bytes. Otras, como Azure DevOps o Mercurial, puede que no.Others, like Azure DevOps or Mercurial, may not. Existen también algunas herramientas basadas en GIT que se basan en la descodificación de texto.Even some git-based tools rely on decoding text.

Cuando esto sucede, asegúrese de llevar a cabo lo siguiente:When this is the case, make sure you:

  • Configure la codificación de texto en el control de código fuente para que coincida con la configuración de VS Code.Configure the text encoding in your source control to match your VS Code configuration.
  • Asegúrese de que todos los archivos se incorporen al control de código fuente en la codificación adecuada.Ensure all your files are checked into source control in the relevant encoding.
  • Sea precavido con los cambios en la codificación que se reciben a través del control de código fuente.Be wary of changes to the encoding received through source control. Una señal clave de esto son unas diferencias que indican la presencia de cambios pero donde nada parece haber cambiado (porque los bytes han cambiado, pero los caracteres no).A key sign of this is a diff indicating changes but where nothing seems to have changed (because bytes have but characters have not).

Entornos de colaboradoresCollaborators' environments

Como paso previo a la configuración del control de código fuente, asegúrese de que los colaboradores en cualquier archivo que comparta no tengan ninguna opción que reemplace la codificación volviendo a codificar los archivos de PowerShell.On top of configuring source control, ensure that your collaborators on any files you share don't have settings that override your encoding by re-encoding PowerShell files.

Otros programasOther programs

Cualquier otro programa que lea o escriba un script de PowerShell puede volver a codificarlo.Any other program that reads or writes a PowerShell script may re-encode it.

Ejemplos:Some examples are:

  • Uso del Portapapeles para copiar y pegar un script.Using the clipboard to copy and paste a script. Esto es habitual en escenarios como:This is common in scenarios like:
    • Copiar un script en una máquina virtualCopying a script into a VM
    • Copiar un script fuera de un correo electrónico o una página webCopying a script out of an email or webpage
    • Copiar un script dentro o fuera de un documento de Microsoft Word o PowerPointCopying a script into or out of a Microsoft Word or PowerPoint document
  • Otros editores de texto, como:Other text editors, such as:
    • NotepadNotepad
    • vimvim
    • Cualquier otro editor de scripts de PowerShellAny other PowerShell script editor
  • Utilidades de edición de texto, como:Text editing utilities, like:
    • Get-Content/Set-Content/Out-File
    • Operadores de redirección de PowerShell, como > y >>PowerShell redirection operators like > and >>
    • sed/awk
  • Programas de transferencia de archivos, como:File transfer programs, like:
    • Un explorador web, al descargar scriptsA web browser, when downloading scripts
    • Un recurso compartido de archivosA file share

Algunas de estas herramientas manejan bytes en lugar de texto, pero otros ofrecen configuraciones de codificación.Some of these tools deal in bytes rather than text, but others offer encoding configurations. En los casos en que deba configurar una codificación, tendrá que hacer la misma codificación que su editor, para evitar problemas.In those cases where you need to configure an encoding, you need to make it the same as your editor encoding to prevent problems.

Otros recursos sobre la codificación en PowerShellOther resources on encoding in PowerShell

Hay algunas otras publicaciones interesantes sobre la codificación y la configuración de la codificación en PowerShell, que vale la pena leer:There are a few other nice posts on encoding and configuring encoding in PowerShell that are worth a read: