かつて山市良と呼ばれたおじさんのブログ

セイテクエンジニアのブログ  かつて山市良と呼ばれたおじさんのブログ  vol.216 コードページとUnicodeのカオスな世界(最終回)|セイテク・シス管道場(Web)

 

 

vol.216 コードページとUnicodeのカオスな世界(最終回)|セイテク・シス管道場(Web)

2026年07月06日配信
2026年07月06日更新
執筆者:山内 和朗

 「セイテク・シス管道場(Web)」では、Windows Serverの要素技術やシステム管理の基本的な部分に焦点を当ててきました。シリーズ最終回の今回は、前回からの続き、コードページとUnicodeの話です。シリーズ最終回恒例の目次付き。

 

コマンドプロンプトと日本語


 前回説明したように、コマンドプロンプト(cmd.exe)は、「ANSI」、つまりアクティブなコードページを基準に動作する世界です。日本語版WindowsにおけるANSIはShift_JISを拡張した「CP932」(Windows-31J)です。TYPEコマンドでテキストファイルを表示する場合、cmd.exeのアクティブなコードページとファイルのエンコードがCP932で一致していなければ日本語は文字化けします。バッチファイルも同様で、記述された文字列は実行時のコードページで解釈されます。そのため、作成時と実行時でコードページが異なると、日本語は簡単に壊れてしまいます。

 

 前回実例で示しましたが、英語版Windowsのcmd.exeのアクティブなコードページは「CP1252」(ただし、cmd.exeは「CP437」)なので、日本語版Windowsで作成された日本語を含む、ANSIで保存されたテキストファイルは、英語版Windowsでは意味不明な文字列を含んでいるように見えます。文字化けの理由は、フォントの有無ではなく、コードページの違いです。


 ASCII文字(英数字と記号)だけで記述されているなら例外です。どの言語のコードページでも、ASCII文字のコードは共通だからです。もっと言えば、ASCII文字のみのファイルは、ANSIエンコードで保存しても、UTF-8(BOMなし)エンコードで保存しても、バイト列は同一になります。“ANSIエンコードを明示的に指定して保存したのに、もう一度メモ帳で開いたらUTF-8として扱われていた”――新しいメモ帳になってからそんな経験はないでしょうか。 ASCII文字だけだとバイト列でエンコードを判別できないため、“現在の”メモ帳はより一般的なUTF-8として開くのです。モダンアプリである現在のメモ帳にとって、ANSIはレガシでローカル依存のエンコードにすぎません。ちなみに、以前のメモ帳でも「UTF-8」エンコードで保存できましたが、BOM付きのUTF-8でした。

 前回の最初に言いましたが、メモ帳の既定は従来「ANSI」でしたが、現在(Windows 10バージョン1903以降、Windows Server 2022以降)は「UTF-8」(BOMなし)に変更されました。そのため、日本語を含むバッチファイルをメモ帳で作成する場合は、エンコード「ANSI」(後述しますがUTF-16 LEでも可)を明示的に指定して保存しないと、正常に実行できません(画面1、画面2)。日本語の表示が文字化けするだけならまだしも、文字化けの影響による1バイトのずれがそのまま別のコマンドへと化けてしまう危険もあります。

 

画面1 メモ帳の既定のエンコードは「UTF-8」。日本語を含むバッチを既定のエンコードで作成すると、文字化けが発生

画面1 メモ帳の既定のエンコードは「UTF-8」。日本語を含むバッチを既定のエンコードで作成すると、文字化けが発生

 

画面2 明示的にエンコード「ANSI」を指定して保存すると、正常に動作する

画面2 明示的にエンコード「ANSI」を指定して保存すると、正常に動作する

 

 現在のメモ帳は、次の文字コード(エンコード)をサポートしています(画面3)。

 

  • ANSI ・・・ 旧メモ帳の既定

  • UTF-16 LE ・・・ 旧メモ帳のUnicode 、BOM付き
  • UTF-16 BE ・・・ 旧メモ帳のUnicode big endian、BOM付き
  • UTF-8  ・・・ 新しいメモ帳の既定、BOMなし、旧メモ帳に選択肢なし
  • UTF-8(BOM付き)・・・ 旧メモ帳のUTF-8、BOM付き

 

画面3 現在のメモ帳がサポートするエンコードの種類。「UTF-8」(BOMなし)が既定

画面3 現在のメモ帳がサポートするエンコードの種類。「UTF-8」(BOMなし)が既定

 ANSIは、これまで何度も言いましたが、文字コードを示すものではなく、アクティブなコードページのことです。新しいメモ帳は4種類のUnicodeをサポートしていますが、既定の「UTF-8」以外はすべてBOM(バイトオーダーマーク)付きです。BOM(Byte Order Mark)とは、Unicodeテキストの先頭に付けられる特殊なバイト列で、そのファイルの文字コードやバイト順を示します(UTF-16 LEはFF FE、UTF-16 BEはFE FF、UTF-8BOM付きはEF BB BF)。ANSIはBOMとは無縁です。そして、ASCII文字のみのANSIとUTF-8(BOMなし)は同一です。なお、より高度なテキストエディターの場合、ANSIというエンコードはエンコードの選択肢として存在しないでしょう。代わりに「日本語(シフトJIS)」のようなエンコードを指定します。

 

PowerShellと日本語

 

 Windowsにはバッチ/スクリプト環境として、cmd.exe以外にも、Windows Script Host(WSH)やPowerShellがあります。そして、vol.196で説明したように、PowerShellにはWindowsに標準搭載されている、.NET FrameworkベースのWindows PowerShell 5.1(PowerShell.exe)、とクロスプラットフォームで.NETベースのPowerShell 7.x(旧称、PowerShell Core)の2つあります。それぞれ、文字コード(エンコード)に関して独自の世界で動いているので厄介なのです。

 

 次の表は、日本語を含むバッチ/スクリプトをメモ帳がサポートするエンコードで保存し、正常に実行できるかどうか(文字化けしないか、コードが壊れないか)を試したものです。バッチファイルとWSHスクリプトは、アクティブなコードページ(ANSI)の世界と思っておけば間違いありません。ただし、XMLベースの.wsfを使用する場合はすべてのエンコードを使用できますが、ANSI(CP932)の場合はShift_JISエンコードを宣言しないとエラーになります。PowerShellは既定はUTF-8(BOMなし) で、完全にUnicodeの世界で動作します。Windows PowerShell 5.1はその中間といったところ。既定はUTF-16 LEなのですが、アクティブなコードページ(ANSI)とUnicode(ただしBOM付き)の両方の世界で動作します。Windows PowerShell 5.1は古いメモ帳と同様に、BOMなしUTF-8が一般的ではなかった時代からあるレガシなコンポーネントです。

 

日本語を含むバッチファイルやスクリプトの実行とエンコードの種類

拡張子 エンジン ANSI(CP932) UTF-16 LE UTF-16 BE UTF-8 UTF-8(BOM付き)
.bat、.cmd cmd.exe ×  ×   ×   × 
.vbs、.js c(w)script.exe ×*1 ×*1  ×*1 
 .wsf   c(w)script.exe  *2  〇   〇 
.ps1、.psm1、.psd1 powershell.exe  〇   〇   〇  ×*3
.ps1、.psm1、.psd1 pwsh.exe ×*4

*1 “コンパイル エラー: 終了していない文字列型の定数です。”または“文字列が正しくありません。”エラー

*2 <?xml version="1.0" encoding="Shift_JIS"?>のように宣言すれば実行可能。エンコード指定がない場合、“テキストをUNICODEに変換できません。”エラー

*3 “文字列に終端記号 " がありません”エラー

*4 日本語が文字化け、文字化けの影響は隣接するコードに影響することも。“The srting is missing the terminater: ".”など

 

 Windows PowerShell 5.1/PowerShellのコマンドレットには、-Encodingパラメーターをサポートしているものがいくつかあります。それらのコマンドレットの-Encordingパラメーター省略時の既定は以下のようになっています。PowerShellはこちらもすべてUTF-8(BOMなし)で統一されていますが、Windows PowerShell 5.1は既定がばらついています。また、BOMなしUTF-8を指定する方法が用意されていません。このWindows PowerShell 5.1のどっちつかずの感じはコードページの世界とUnicodeの世界の橋渡し的な意味もあるのでしょうが、注意が必要なところです。

 

-Encodingパラメーター省略時の既定値

コマンドレット(リンク先はMicrosoft Learn) Windows PowerShell 5.1(powershell.exe) PowerShell 7.x(pwsh.exe)
 Get-Content   -Encoding Default  -Encoding utf8NoBOM
 Set-Content   -Encoding Default    -Encoding utf8NoBOM
 Add-Content 

 -Encoding Default  

 -Encoding utf8NoBOM
 Export-CSV   -Encoding ASCII  -Encoding utf8NoBOM
 Export-Clixml  -Encoding Default  -Encoding utf8NoBOM
 Out-File   -Encoding unicode   -Encoding utf8NoBOM 

 ※DefaultはANSI、unicodeはUTF-16 LE 、utf8NoBOMはUTF-8(BOMなし)のこと

※パラメーターに使用できる値:
 Windows PowerShell 5.1: Ascii|BigEndianUnicode|BigEndianUTF32|Byte|Default(通常、ANSI)|Oem|String|Unicode|Unknown|UTF7|UTF8|UTF32

 PowerShlel 7.x: ascii|ansi|bigendianunicode|bigendianutf32|oem|unicode|utf7|utf8|utf8BOM|utf8NoBOM|utf32

 ちなみに、>によるファイルリダイレクトは、Out-Fileと同様です。例えば「echo あいうえお > ファイル名.txt」をコマンドプロンプト(cmd.exe)、Windows PowerShell 5.1、PowerShell「(Windows PowerShell/PowerShellでのechoはWrite-Hostのエイリアス)、で実行すると、作成されるファイルのエンコードはそれぞれANSI、UTF-16 LE、UTF-8(BOMなし)になります。TYPEコマンド(PowerShellではGet-Contentのエイリアス)で表示すると、コマンドプロンプトとWindows PowerShell 5.1はお互いのファイルが見えますが、PowerShellではANSIだけが文字化けします(画面4)。 Windows PowerShell 5.1とPowerShellで文字化けしたファイルを正しく読み取るには、TYPE(Get-Contentのエイリアス)に-Encodingパラメーターでエンコードを指定します。

 

画面5 同じコマンドラインを実行しても、出来上がるファイルのエンコードはすべて異なる。左からPowerShell(pwsh.exe)、Windows PowerShell(powershell.exe)、コマンドプロンプト(cmd.exe)

画面4 同じコマンドラインを実行しても、出来上がるファイルのエンコードはすべて異なる。左からPowerShell(pwsh.exe)、Windows PowerShell(powershell.exe)、コマンドプロンプト(cmd.exe)

 

 “ANSIで保存する”という習慣、“ANSIなら安心”という思い込みは、PowerShellが主流になりつつある現在では、むしろトラブルの原因になりかねません。新しいメモ帳が既定にしているように、理想はUTF-8(BOMなし)*5です。しかし、Windowsに標準搭載されているのは、UTF-8(BOMなし)を正しく扱えない場合があるWindows PowerShell 5.1であり、すべての環境でPowerShell 7.xを利用できるわけではないのが現実です。コマンドプロンプト(cmd.exe)ではANSI、それ以外の環境のUnicodeテキストはUTF-8(BOM付き)で保存する――それが現時点での現実的な安全策と言えるでしょう。 バッチ内でCHCPコマンドでコードページを切り替えるなんて方法もありますが、かえってカオスな世界が広がるだけだと思います。
*5 以下はUnicodeの古いバージョンですが、UTF-8にはBOMは必須ではなく、推奨もされていないと記載されています。
参考: Use of a BOM is neither required nor recommended for UTF-8, but ...
|Unicode Standard, Version 5.0(unicode.org)

 

 もっとも、バッチやスクリプトには日本語を使わない、ASCII文字だけにすると決めてしまえば、文字コード(エンコード)の問題に振り回されることなんてありません。  私自身もそのようにして、余計な面倒から距離を置いてきました。

・・・

 

「セイテク・シス管道場(Web)」シリーズの目次

  1. ログオン/ログオフ、サインイン/サインアウト、あなたは何派?
  2. セッションとデスクトップと私
  3. Administratorの名前変更はすぐバレるーSIDの話
  4. Windows PowerShellとPowerShell(pwsh)
  5. 役割管理だけじゃない、サーバーマネージャーの真の価値
  6. タスクマネージャーによるプロセス/サービス制御
  7. タスクマネージャーでCPU使用率を監視する
  8. タスクマネージャーが示すCPU使用率の秘密
  9. 信頼性モニター、使わないのはもったいない
  10. パフォーマンスモニターでできること、できないこと
  11. その常識はもう古い?-パフォーマンスカウンターとの付き合い方(1)
  12. ベースラインを把握する-パフォーマンスカウンターとの付き合い方(2)
  13. PowerShellで自在に!-パフォーマンスカウンターとの付き合い方(3)
  14. 限界を知る-パフォーマンスカウンターとの付き合い方(4)
  15. 仮想環境での考慮事項ーパフォーマンスカウンターとの付き合い方(5) 
  16. システムインサイトによる容量予測
  17. イベントログを使いこなせ(その1)
  18. イベントログを使いこなせ(その2)
  19. イベントログからタスクへバトンリレー
  20. タスクスケジューラともっと仲良くなろう
  21. タスクからの通知機能廃止理由と現代的な代替手段
  22. タスクスケジューラーとDST: 丑三つ時が消えない日本でよかった
  23. “ANSI≒Shift_JIS”が日本のWindowsでしか通用しない理由
  24. コードページとUnicodeのカオスな世界(最終回)

 セイテク・シス管道場(Web) (1) |・・・|(11)(12)(13)(14)(15)(16)(17)(18)(19)(20)(21)(22)(23)|(24)        

blog_yamanxworld_subscribe

blog_yamanxworld_comment

blog_yamanxworld_WP_ws2025

最新記事