VS Code と PowerShell でのファイルのエンコードの概要Understanding file encoding in VS Code and PowerShell

VS Code を使用して PowerShell スクリプトを作成および編集するときは、正しい文字エンコード形式を使用してファイルを保存することが重要です。When using VS Code to create and edit PowerShell scripts, it is important that your files are saved using the correct character encoding format.

ファイルのエンコードの概要とそれが重要な理由What is file encoding and why is it important?

VS Code により、人間が文字列をバッファーに入力することと、バイトのブロックをファイル システムに読み取りおよび書き込みすることの間のインターフェイスが管理されます。VS Code manages the interface between a human entering strings of characters into a buffer and reading/writing blocks of bytes to the filesystem. VS Code では、ファイルを保存するとき、テキスト エンコードを使用して各文字がどのバイトになるかが判断されます。When VS Code saves a file, it uses a text encoding to decide what bytes each character becomes. 詳細については、「about_Character_Encoding」をご覧ください。For more information, see about_Character_Encoding.

同様に、PowerShell によりスクリプトが実行されるときは、ファイルを 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. VS Code によりファイルが書き込まれ、PowerShell によりファイルが読み取られるため、これらでは同じエンコード システムを使用する必要があります。Since VS Code writes the file and PowerShell reads the file, they need to use the same encoding system. PowerShell スクリプトを解析するこのプロセスは、 バイト -> 文字 -> トークン -> 抽象構文木 -> 実行 の順に行われます。This process of parsing a PowerShell script goes: bytes -> characters -> tokens -> abstract syntax tree -> execution.

VS Code と PowerShell は両方とも、実用的な既定のエンコード構成でインストールされています。Both VS Code and PowerShell are installed with a sensible default encoding configuration. ただし、PowerShell により使用される既定のエンコードは、PowerShell Core (v6.x) のリリースで変わりました。However, the default encoding used by PowerShell has changed with the release of PowerShell Core (v6.x). VS Code で PowerShell または PowerShell 拡張機能を使用しても確実に問題がないようにするには、VS Code と PowerShell の設定を正しく構成する必要があります。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.

エンコード問題の一般的な原因Common causes of encoding issues

エンコードの問題は、VS Code またはスクリプト ファイルのエンコードが、想定される PowerShell のエンコードと一致しない場合に発生します。Encoding problems occur when the encoding of VS Code or your script file does not match the expected encoding of PowerShell. PowerShell でファイルのエンコードが自動的に決定される方法はありません。There is no way for PowerShell to automatically determine the file encoding.

7 ビット ASCII 文字セット以外の文字を使用している場合は、エンコードの問題が発生する可能性が高くなります。You're more likely to have encoding problems when you're using characters not in the 7-bit ASCII character set. 次に例を示します。For example:

  • em ダッシュ ()、改行なしスペース ( )、左二重引用符 (") などのアルファベット以外の拡張文字Extended non-letter characters like em-dash (), non-breaking space ( ) or left double quotation mark (")
  • アクセント付きラテン文字 (Éü)Accented latin characters (É, ü)
  • キリル文字などの非ラテン文字 (ДЦ)Non-latin characters like Cyrillic (Д, Ц)
  • CJK 文字 ()CJK characters (, , )

エンコードの問題の一般的な理由は次のとおりです。Common reasons for encoding issues are:

  • VS Code と PowerShell のエンコードが既定値から変更されていません。The encodings of VS Code and PowerShell have not been changed from their defaults. PowerShell 5.1 以下では、既定のエンコードは VS Code とは異なります。For PowerShell 5.1 and below, the default encoding is different from VS Code's.
  • 別のエディターでファイルが開かれ、新しいエンコードで上書きされました。Another editor has opened and overwritten the file in a new encoding. 多くの場合、これは ISE で発生します。This often happens with the ISE.
  • VS Code または PowerShell で想定されているエンコードとは異なるエンコードでファイルがソース管理にチェックインされています。The file is checked into source control in an encoding that is different from what VS Code or PowerShell expects. これは、共同作業者が異なるエンコード構成のエディターを使用している場合に発生する可能性があります。This can happen when collaborators use editors with different encoding configurations.

エンコードの問題が発生したときの判断方法How to tell when you have encoding issues

多くの場合、エンコード エラーはスクリプト内の解析エラーとして現れます。Often encoding errors present themselves as parse errors in scripts. スクリプト内に通常とは異なる文字シーケンスが見つかった場合は、それが問題になる可能性があります。If you find strange character sequences in your script, this can be the problem. 以下の例では、半角ダッシュ () が â€" という文字で表示されています。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

この問題は、VS Code により UTF-8 の文字 がバイト 0xE2 0x80 0x93 としてエンコードされるために発生します。This problem occurs because VS Code encodes the character in UTF-8 as the bytes 0xE2 0x80 0x93. このようなバイトが Windows-1252 としてデコードされると、â&euro;" という文字に解釈されます。When these bytes are decoded as Windows-1252, they are interpreted as the characters â&euro;".

よく見られる通常とは異なる文字シーケンスの例を次に示します。Some strange character sequences that you might see include:

  • の代わりに â&euro;"â&euro;" instead of
  • の代わりに â&euro;"â&euro;" instead of
  • Ä の代わりに Ä2Ä2 instead of Ä
  • の代わりに Â (改行なしスペース)Â instead of (a non-breaking space)
  • é の代わりに Ã&copy;Ã&copy; instead of é

こちらの便利な関連ドキュメントには、UTF-8/Windows-1252 エンコードの問題を示す一般的なパターンの一覧が掲載されています。This handy reference lists the common patterns that indicate a UTF-8/Windows-1252 encoding problem.

VS Code の PowerShell 拡張機能とエンコードの相互作用How the PowerShell extension in VS Code interacts with encodings

PowerShell 拡張機能は、さまざまな方法でスクリプトとやりとりします。The PowerShell extension interacts with scripts in a number of ways:

  1. スクリプトが VS Code により編集されると、そのコンテンツは VS Code によって拡張機能に送信されます。When scripts are edited in VS Code, the contents are sent by VS Code to the extension. 言語サーバー プロトコルでは、このコンテンツを UTF-8 で転送することを義務付けています。The Language Server Protocol mandates that this content is transferred in UTF-8. そのため、拡張機能が不適切なエンコードが取得されることはありません。Therefore, it is not possible for the extension to get the wrong encoding.
  2. 統合されたコンソールでスクリプトを直接実行されると、PowerShell によってファイルから直接読み取られます。When scripts are executed directly in the Integrated Console, they're read from the file by PowerShell directly. PowerShell のエンコードが VS Code のエンコードと異なる場合は、ここで何か問題が起こる可能性があります。If PowerShell's encoding differs from VS Code's, something can go wrong here.
  3. VS Code で開かれているスクリプトにより VS Code で開かれていない別のスクリプトが参照されている場合、拡張機能はフォール バックして、そのスクリプトのコンテンツをファイル システムから読み込みます。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. PowerShell 拡張機能の既定は UTF-8 エンコードですが、バイト オーダー マーク (BOM) 検出を使用して正しいエンコードが選択されます。The PowerShell extension defaults to UTF-8 encoding, but uses byte-order mark, or BOM, detection to select the correct encoding.

問題は、BOM なしの形式 (BOM なしの UTF-8Windows-1252 など) のエンコードを想定しているときに発生します。The problem occurs when assuming the encoding of BOM-less formats (like UTF-8 with no BOM and Windows-1252). PowerShell 拡張機能の既定値は UTF-8 です。The PowerShell extension defaults to UTF-8. この拡張機能では VS Code のエンコード設定を変更できません。The extension cannot change VS Code's encoding settings. 詳細については、問題番号 824 を参照してください。For more information, see issue #824.

適切なエンコードの選択Choosing the right encoding

システムやアプリケーションごとに使用しているエンコードが異なる可能性があります。Different systems and applications can use different encodings:

  • 現在、.NET Standard、Web、Linux の世界では、UTF-8 が主流のエンコードです。In .NET Standard, on the web, and in the Linux world, UTF-8 is now the dominant encoding.
  • 多くの .NET Framework アプリケーションは UTF-16 を使用しています。Many .NET Framework applications use UTF-16. 歴史的な理由から、これは "Unicode" と呼ばれることもあり、現在では UTF-8 と 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.
  • Windows では、Unicode より前のネイティブ アプリケーションの多くが既定で Windows-1252 を使用し続けています。On Windows, many native applications that predate Unicode continue to use Windows-1252 by default.

Unicode エンコードには、バイト オーダー マーク (BOM) の概念もあります。Unicode encodings also have the concept of a byte-order mark (BOM). BOM はテキストの先頭にあり、これによりテキストが使用しているエンコードがデコーダーに通知されます。BOMs occur at the beginning of text to tell a decoder which encoding the text is using. マルチバイト エンコードの場合、BOM によりエンコードのエンディアンが示されます。For multi-byte encodings, the BOM also indicates endianness of the encoding. BOM は、Unicode 以外のテキストにはまず出現しないバイトになるように設計されているため、BOM が存在する場合、そのテキストは Unicode であると合理的に推測できます。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.

BOM はオプションであり、Linux の世界ではそれほど採用されていません。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. ほとんどの Linux アプリケーションでは、テキスト入力が UTF-8 でエンコードされていると想定されています。Most Linux applications presume that text input is encoded in UTF-8. 多くの Linux アプリケーションは BOM を認識して正しく処理しますが、認識しないものもあります。そのため、そのようなアプリケーションで処理されたテキストにアーティファクトが生じます。While many Linux applications will recognize and correctly handle a BOM, a number do not, leading to artifacts in text manipulated with those applications.

したがって :Therefore :

  • 主に Windows アプリケーションと Windows PowerShell を使用している場合は、BOM ありの UTF-8 または 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.
  • 複数のプラットフォームにまたがって作業する場合は、BOM ありの UTF-8 をお勧めします。If you work across platforms, you should prefer UTF-8 with BOM.
  • 主に Linux 関連のコンテキストで作業する場合は、BOM なしの UTF-8 をお勧めします。If you work mainly in Linux-associated contexts, you should prefer UTF-8 without BOM.
  • Windows-1252 とラテン-1 は基本的にレガシ エンコードであり、できれば避けてください。Windows-1252 and latin-1 are essentially legacy encodings that you should avoid if possible. ただし、一部の古い Windows アプリケーションではそれらに依存している可能性があります。However, some older Windows applications may depend on them.
  • スクリプトの署名はエンコードに依存している点にも注意してください。つまり、署名されたスクリプトのエンコードを変更するには再署名が必要です。It's also worth noting that script signing is encoding-dependent, meaning a change of encoding on a signed script will require resigning.

VS Code の構成Configuring VS Code

VS Code の既定のエンコードは BOM なしの UTF-8 です。VS Code's default encoding is UTF-8 without BOM.

VS Code のエンコードを設定するには、VS Code の設定に移動し (Ctrl+)、"files.encoding" 設定を指定します。To set VS Code's encoding, go to the VS Code settings (Ctrl+,) and set the "files.encoding" setting:

"files.encoding": "utf8bom"

次のような値を指定できます。Some possible values are:

GUI ビューでこのドロップダウンを表示するか、JSON ビューですべてを確認できます。You should get a dropdown for this in the GUI view, or completions for it in the JSON view.

また、可能であれば、以下を追加してエンコードを自動検出することもできます。You can also add the following to autodetect encoding when possible:

"files.autoGuessEncoding": true

これらの設定がすべてのファイルの種類に影響しないようにする場合、VS Code では言語ごとに構成することもできます。If you don't want these settings to affect all files types, VS Code also allows per-language configurations. [<language-name>] フィールドに設定を指定して、言語固有の設定を作成します。Create a language-specific setting by putting settings in a [<language-name>] field. 次に例を示します。For example:

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

また、Gremlins tracker for Visual Studio Code をインストールすることを検討してください。You may also want to consider installing the Gremlins tracker for Visual Studio Code. この拡張機能により、目に見えないか他の通常の文字のように見えるため、文字化けしやすい特定の Unicode 文字が明らかになります。This extension reveals certain Unicode characters that easily corrupted because they are invisible or look like other normal characters.

PowerShell の構成Configuring PowerShell

PowerShell の既定のエンコードはバージョンによって異なります。PowerShell's default encoding varies depending on version:

  • PowerShell 6 以降では、既定のエンコードはすべてのプラットフォームで BOM なしの UTF-8 です。In PowerShell 6+, the default encoding is UTF-8 without BOM on all platforms.
  • Windows PowerShell では、既定のエンコードは通常 Windows-1252 (拡張子は latin-1) であり、ISO 8859-1 とも呼ばれます。In Windows PowerShell, the default encoding is usually Windows-1252, an extension of latin-1, also known as ISO 8859-1.

PowerShell 5 以降では、以下のように既定のエンコードを確認できます。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, @())
  }

次のスクリプトを使用して、PowerShell セッションが 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
}

より一般的にはプロファイル設定を使用して、特定のエンコードを使用するように PowerShell を構成することができます。It's possible to configure PowerShell to use a given encoding more generally using profile settings. 次の記事をご覧ください。See the following articles:

PowerShell に特定の入力エンコードの使用を強制することはできません。It's not possible to force PowerShell to use a specific input encoding. ロケールが en-US に設定された Windows で実行される PowerShell 5.1 以前では、BOM がない場合、既定値は Windows-1252 エンコードです。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. 他のロケール設定では、別のエンコードを使用できます。Other locale settings may use a different encoding. 相互運用性を確保するには、BOM が含まれる Unicode 形式でスクリプトを保存することをお勧めします。To ensure interoperability, it's best to save scripts in a Unicode format with a BOM.

重要

PowerShell スクリプトに触れる他のツールがある場合、そのツールがエンコードの選択の影響を受ける場合や、ツールによってスクリプトが別のエンコードに再エンコードされる場合があります。Any other tools you have that touch PowerShell scripts may be affected by your encoding choices or re-encode your scripts to another encoding.

既存のスクリプトExisting scripts

既にファイル システム上にあるスクリプトは、必要に応じて新しく選択したエンコードに再エンコードします。Scripts already on the file system may need to be re-encoded to your new chosen encoding. VS Code の下部のバーに、UTF-8 というラベルが表示されます。In the bottom bar of VS Code, you'll see the label UTF-8. クリックしてアクション バーを開き、 [エンコード付きで保存] を選択します。Click it to open the action bar and select Save with encoding. ここで、そのファイル用に新しいエンコードを選択できます。You can now pick a new encoding for that file. 完全な手順については、VS Code のエンコードに関するページを参照してください。See VS Code's encoding for full instructions.

複数のファイルを再エンコードする必要がある場合は、次のスクリプトを使用できます。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
}

PowerShell Integrated Scripting Environment (ISE)The PowerShell Integrated Scripting Environment (ISE)

PowerShell ISE を使用してスクリプトも編集する場合は、そこでエンコード設定を同期する必要があります。If you also edit scripts using the PowerShell ISE, you need to synchronize your encoding settings there.

ISE で BOM を尊重する必要がありますが、リフレクションを使用してエンコードを設定することもできます。The ISE should honor a BOM, but it's also possible to use reflection to set the encoding. これはスタートアップ後には保持されないことに注意してください。Note that this wouldn't be persisted between startups.

ソース管理ソフトウェアSource control software

git などの一部のソース管理ツールはエンコードを無視します (git は単にバイトを追跡します)。Some source control tools, such as git, ignore encodings; git just tracks the bytes. 他のもの (Azure DevOps や Mercurial など) はそうではない場合があります。Others, like Azure DevOps or Mercurial, may not. 一部の git ベースのツールでさえ、テキストのデコードに依存しています。Even some git-based tools rely on decoding text.

その場合は、次のことを確認してください。When this is the case, make sure you:

  • VS Code の構成と一致するように、ソース管理でテキスト エンコードを構成します。Configure the text encoding in your source control to match your VS Code configuration.
  • すべてのファイルが適切なエンコードでソース管理に確実にチェックインされているようにします。Ensure all your files are checked into source control in the relevant encoding.
  • ソース管理を介して受信したエンコードの変化に注意します。Be wary of changes to the encoding received through source control. これを示す主な兆候は変化を示す差異ですが、何も変わっていないように見えます (バイトは変わっていますが、文字は変わっていないため)。A key sign of this is a diff indicating changes but where nothing seems to have changed (because bytes have but characters have not).

共同作業者の環境Collaborators' environments

ソース管理の構成に加え、共有するファイルの共同作業者が 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.

その他のプログラムOther programs

PowerShell スクリプトの読み取りまたは書き込みを行う他のプログラムが、再エンコードする可能性があります。Any other program that reads or writes a PowerShell script may re-encode it.

いくつかの例を次に示します。Some examples are:

  • クリップボードを使用してスクリプトをコピーして貼り付ける。Using the clipboard to copy and paste a script. これは次のようなシナリオで一般的です。This is common in scenarios like:
    • スクリプトを VM にコピーするCopying a script into a VM
    • 電子メールまたは Web ページからスクリプトをコピーするCopying a script out of an email or webpage
    • Microsoft Word または PowerPoint ドキュメントとの間でスクリプトをコピーするCopying a script into or out of a Microsoft Word or PowerPoint document
  • 次のようなその他のテキスト エディター:Other text editors, such as:
    • メモ帳Notepad
    • vimvim
    • その他の PowerShell スクリプト エディターAny other PowerShell script editor
  • 次のようなテキスト編集ユーティリティ:Text editing utilities, like:
    • Get-Content/Set-Content/Out-File
    • PowerShell リダイレクト演算子 (>>> など)PowerShell redirection operators like > and >>
    • sed/awk
  • 次のようなファイル転送プログラム:File transfer programs, like:
    • Web ブラウザー (スクリプトのダウンロード時)A web browser, when downloading scripts
    • ファイル共有A file share

このようなツールの一部はテキストではなくバイトで処理しますが、エンコードの構成機能が用意されているツールもあります。Some of these tools deal in bytes rather than text, but others offer encoding configurations. エンコードを構成する必要がある場合は、問題を防ぐために、それをエディターのエンコードと同じにする必要があります。In those cases where you need to configure an encoding, you need to make it the same as your editor encoding to prevent problems.

PowerShell でのエンコードに関するその他のリソースOther resources on encoding in PowerShell

PowerShell でのエンコードとエンコードの構成に関するお勧めの投稿が他にもいくつかあります。There are a few other nice posts on encoding and configuring encoding in PowerShell that are worth a read: