Примечание
Для доступа к этой странице требуется авторизация. Вы можете попробовать войти или изменить каталоги.
Для доступа к этой странице требуется авторизация. Вы можете попробовать изменить каталоги.
При использовании VS Code для создания и редактирования скриптов PowerShell важно сохранить файлы с помощью правильного формата кодировки символов.
Что такое кодировка файлов и почему это важно?
VS Code управляет интерфейсом между вводом строк символов в буфер и чтением/записью блоков байтов в файловую систему. При сохранении файла VS Code использует текстовую кодировку, чтобы определить, в какие байты преобразуется каждый символ. Дополнительные сведения см. в about_Character_Encoding.
Аналогичным образом, когда PowerShell запускает скрипт, он должен преобразовать байты в файл в символы, чтобы восстановить файл в программу PowerShell. Так как VS Code записывает файл и PowerShell считывает файл, они должны использовать ту же систему кодирования. Этот процесс анализа скрипта PowerShell идет: байтов ->символов ->токенов ->абстрактного синтаксического дерева ->выполнения.
Vs Code и PowerShell устанавливаются с разумной конфигурацией кодирования по умолчанию. Однако кодировка по умолчанию, используемая PowerShell, изменилась с выпуском PowerShell 6. Чтобы не было проблем с использованием PowerShell или расширения PowerShell в VS Code, необходимо правильно настроить параметры VS Code и PowerShell.
Распространенные причины проблем с кодировкой
Проблемы с кодировкой возникают, когда кодировка VS Code или файл скрипта не соответствует ожидаемой кодировке PowerShell. Для PowerShell невозможно автоматически определить кодировку файлов.
При использовании символов, не входящих в 7-разрядныйнабор символов ASCII, скорее всего, возникают проблемы с кодировкой. Например:
- Расширенные символы, отличные от букв, такие как em-dash (
—
), неразрывный пробел ("
) - Акцентированные латинские символы (
É
,ü
) - Не латинские символы, такие как кириллица (
Д
,Ц
) - Символы CJK (
本
,화
,が
)
Распространенные причины проблем с кодировкой:
- Кодировки VS Code и PowerShell не были изменены по умолчанию. Для PowerShell 5.1 и ниже кодировка по умолчанию отличается от VS Code.
- Другой редактор открыл и перезаписал файл в новой кодировке. Это часто происходит с ISE.
- Файл проверяется в системе управления версиями в кодировке, отличной от ожидаемого VS Code или PowerShell. Это может произойти, когда сотрудники используют редакторы с различными конфигурациями кодирования.
Как определить проблемы с кодировкой
Часто ошибки кодирования представляют собой ошибки синтаксического анализа в скриптах. Если в скрипте находятся странные последовательности символов, это может быть проблема. В приведенном ниже примере en-dash (–
) отображается как символы â€"
:
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
Эта проблема возникает, так как VS Code кодирует символ –
в UTF-8 в качестве 0xE2 0x80 0x93
байтов. Когда эти байты декодируются как Windows-1252, они интерпретируются как символы â€"
.
Некоторые странные последовательности символов, которые вы можете увидеть:
-
â€"
вместо–
(en-dash) -
â€"
вместо—
(em-dash) -
Ä2
вместоÄ
-
Â
вместо -
é
вместоé
Этот удобный справочник содержит общие шаблоны, указывающие на проблему кодирования UTF-8/Windows-1252.
Взаимодействие расширения PowerShell в VS Code с кодировками
Расширение PowerShell взаимодействует со скриптами несколькими способами:
- Когда скрипты редактируются в VS Code, содержимое отправляется VS Code в расширение. Протокол сервера языка требует передачи этого содержимого в UTF-8. Поэтому расширение не может получить неправильное кодирование.
- Когда скрипты выполняются непосредственно в интегрированной консоли, они считываются из файла с помощью PowerShell напрямую. Если кодировка PowerShell отличается от VS Code, то что-то может пойти не так здесь.
- Когда скрипт, открытый в VS Code, ссылается на другой скрипт, который не открыт в VS Code, расширение возвращается к загрузке содержимого этого скрипта из файловой системы. Расширение PowerShell по умолчанию использует кодировку UTF-8, но использует метку порядка байтовили BOM, чтобы выбрать правильную кодировку.
Проблема возникает при условии кодирования форматов без BOM (например, UTF-8 без BOM и Windows-1252). Расширение PowerShell по умолчанию используется для UTF-8. Расширение не может изменить параметры кодирования VS Code. Дополнительные сведения см. в статье проблема no 824.
Выбор правильной кодировки
Различные системы и приложения могут использовать разные кодировки:
- В .NET Standard, в Интернете и в мире Linux UTF-8 теперь является доминирующей кодировкой.
- Многие приложения .NET Framework используют UTF-16. По историческим причинам это иногда называется «Юникод», термин, который теперь относится к широкому стандарту, включающему как UTF-8, так и UTF-16.
- В Windows многие встроенные приложения, которые были созданы до принятия Юникода, продолжают использовать Windows-1252 по умолчанию.
Кодировки Юникода также имеют понятие метки порядка байтов (BOM). BOMs появляются в начале текста, чтобы указать декодировщику, какую кодировку использует текст. Для многобайтовых кодировок BOM также указывает порядок байтов кодировки. BOM предназначены быть байтами, которые редко встречаются в тексте не Юникода, что позволяет разумно предположить, что текст является Юникодом при наличии BOM.
BOM является необязательной, и их внедрение не так популярно в мире Linux, так как везде используется надежный стандарт UTF-8. Большинство приложений Linux предполагают, что ввод текста закодирован в UTF-8. Хотя многие приложения Linux распознают и правильно обрабатывают BOM, некоторые из них этого не делают, что приводит к артефактам в тексте, обрабатываемом этими приложениями.
поэтому:
- Если вы работаете в основном с приложениями Windows и Windows PowerShell, следует предпочесть кодировку, например UTF-8 с BOM или UTF-16.
- Если вы работаете на разных платформах, следует использовать UTF-8 с BOM.
- Если вы работаете главным образом в контекстах, связанных с Linux, следует предпочесть UTF-8 без BOM.
- Windows-1252 и latin-1 по сути являются устаревшими кодировками, которые следует избегать, если это возможно. Однако некоторые старые приложения Windows могут зависеть от них.
- Также стоит отметить, что подписывание скрипта зависимо от кодирования, то есть изменение кодировки в подписанном скрипте потребует отставки.
Настройка VS Code
Кодировка VS Code по умолчанию — UTF-8 без BOM.
Чтобы задать
"files.encoding": "utf8bom"
Ниже приведены некоторые возможные значения:
-
utf8
: [UTF-8] без BOM -
utf8bom
: [UTF-8] с BOM -
utf16le
: Маленький эндиан [UTF-16] -
utf16be
: Большой эндиан [UTF-16] -
windows1252
: [Windows-1252]
Вы должны получить раскрывающийся список в представлении графического интерфейса пользователя или варианты завершения в представлении JSON.
Вы также можете добавить следующее для автоматического определения кодировки, если это возможно:
"files.autoGuessEncoding": true
Если вы не хотите, чтобы эти параметры влияли на все типы файлов, VS Code также позволяет настраивать конфигурации для каждого языка. Создайте параметр для конкретного языка, поместив параметры в поле [<language-name>]
. Например:
"[powershell]": {
"files.encoding": "utf8bom",
"files.autoGuessEncoding": true
}
Вам также может потребоваться установить трекер Gremlins для Visual Studio Code. Это расширение показывает определенные символы Юникода, которые легко повреждены, так как они невидимы или выглядят как другие обычные символы.
Настройка PowerShell
Кодировка PowerShell по умолчанию зависит от версии:
- В PowerShell 6+ кодировка по умолчанию — UTF-8 без BOM на всех платформах.
- В Windows PowerShell кодировка по умолчанию обычно является Windows-1252, которая является расширением latin-1 (также известной как ISO 8859-1).
В PowerShell 5+ вы можете найти кодировку по умолчанию с помощью следующего:
[psobject].Assembly.GetTypes() | Where-Object { $_.Name -eq 'ClrFacade'} |
ForEach-Object {
$_.GetMethod('GetDefaultEncoding', [System.Reflection.BindingFlags]'nonpublic,static').Invoke($null, @())
}
Следующий скрипт можно использовать для определения, какое кодирование предполагает ваш сеанс PowerShell для скрипта без 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
}
Можно настроить PowerShell для использования заданной кодировки в целом с помощью параметров профиля. См. следующие статьи:
- @mklement0ответ о кодировке PowerShell в Stack Overflow.
- @rkeithhillзапись блога о работе с входными данными UTF-8 без BOM в PowerShell.
Невозможно принудительно использовать кодирование входных данных PowerShell. PowerShell 5.1 и более ранние версии, работающие в Windows с локалью, установленной на en-US, по умолчанию настроены на использование кодировки Windows-1252 при отсутствии BOM. Другие региональные настройки могут использовать другую кодировку. Чтобы обеспечить взаимодействие, рекомендуется сохранять скрипты в формате Юникода с помощью BOM.
Важный
Любые другие инструменты, которые касаются скриптов PowerShell, могут повлиять на выбор кодирования или повторно закодировать скрипты в другую кодировку.
Существующие скрипты
Скрипты, уже размещенные в файловой системе, могут быть перекодированы в новую выбранную кодировку. В нижней строке VS Code вы увидите метку UTF-8. Щелкните его, чтобы открыть панель действий и выберите Сохранить с помощью кодировки. Теперь вы можете выбрать новую кодировку для этого файла. Полные инструкции см. в кодировке VS Code.
Если необходимо повторно закодировать несколько файлов, можно использовать следующий сценарий:
Get-ChildItem *.ps1 -Recurse | ForEach-Object {
$content = Get-Content -Path $_
Set-Content -Path $_.FullName -Value $content -Encoding UTF8 -PassThru -Force
}
Интегрированная среда сценариев PowerShell (ISE)
Если вы также редактируете скрипты с помощью среды сценариев PowerShell, необходимо синхронизировать параметры кодирования там.
ISE должен учитывать BOM, но также можно использовать отражение для задания кодировки. Обратите внимание, что это не будет сохранено между запусками.
Система контроля версий
Некоторые средства управления версиями, такие как git, игнорируют кодировки; Git просто отслеживает байты. Другие, такие как Azure DevOps или Mercurial, могут этого не поддерживать. Даже некоторые средства на основе Git полагаются на декодирование текста.
В этом случае убедитесь, что вы:
- Настройте кодировку текста в используемой вами системе управления версиями для соответствия конфигурации VS Code.
- Убедитесь, что все ваши файлы проверены в системе контроля версий в соответствующей кодировке.
- Будьте осторожны с изменениями в кодировке, полученной через систему контроля версий. Ключевым признаком этого является разница, указывающая на изменения, хотя кажется, что ничего не изменилось (поскольку изменились байты, но символы — нет).
Среды сотрудников
Помимо правильной настройки системы управления версиями, убедитесь, что настройки ваших сотрудников не переопределяют вашу кодировку при совместной работе с файлами PowerShell.
Другие программы
Любая другая программа, которая считывает или записывает скрипт PowerShell, может повторно закодировать его.
Ниже приведены некоторые примеры.
- Использование буфера обмена для копирования и вставки скрипта. Это часто происходит в таких сценариях:
- Копирование скрипта в виртуальную машину
- Копирование скрипта из электронной почты или веб-страницы
- Копирование скрипта в документ Microsoft Word или PowerPoint или из него
- Другие текстовые редакторы, такие как:
- Блокнот
- энтузиазм
- Любой другой редактор скриптов PowerShell
- Служебные программы редактирования текста, такие как:
Get-Content
/Set-Content
/Out-File
- Операторы перенаправления PowerShell, такие как
>
и>>
sed
/awk
- Программы передачи файлов, такие как:
- Веб-браузер при скачивании скриптов
- Общий доступ к файлам
Некоторые из этих средств занимаются байтами, а не текстом, но другие предлагают конфигурации кодирования. В тех случаях, когда необходимо настроить кодировку, необходимо сделать его таким же, как кодирование редактора, чтобы предотвратить проблемы.
Другие ресурсы по кодировке в PowerShell
Есть несколько других хороших записей по кодировке и настройке кодирования в PowerShell, которые стоит прочитать:
- о_Кодировке_Символов
- Краткое описание @mklement0 по кодированию PowerShell на Stack Overflow
- Предыдущие проблемы, открытые на VS Code-PowerShell из-за проблем с кодировкой:
- Классическая статья Джоэла о Software о Юникоде
- кодировка в .NET Standard
PowerShell