Python と Windows の地雷

複数プロジェクトで踏んだ、Windows 由来の罠。

  • ファイル入出力に encoding="utf-8" を明示:省略すると Windows 既定が cp932 になり、日本語を含む JSON/テキストで UnicodeDecodeError。読み書き両方で指定する(gemini-rag)。
  • SetForegroundWindow は他プロセスの窓を前面化できない:OS レベルの制限で、別アプリのウィンドウを プログラムからアクティブにするのは基本拒否される。AttachThreadInput でスレッドをアタッチする回避策は あるが、他ウィンドウへの意図しない副作用リスクがあり安易に使えない(mouse-release の F8 再拘束が 不安定なのはこれが根本原因・未解決)。
  • .bat と .ps1 で正解が違う(2026-09-07 に踏んだ):.bat に BOM を付けてはいけない。 cmd.exe は bat を OEM コードページ(日本語環境で cp932)で読むので、UTF-8 だとコメントが 文字化けし、BOM を付けると 1 行目が ・ソ@echo off になって @echo off が効かなくなる。 その結果 rem 行が 1 行ずつ画面に出て、化けた断片がコマンドとして実行されようとする (start 行自体は動くので「動いてはいるが大量にエラーが出る」という分かりにくい壊れ方をする)。 .bat は cp932・CRLF・BOM なしで保存する。.ps1 は下記のとおり BOM 付きが正解で、 同じ「日本語スクリプト」でも逆になる。
  • 日本語を含む .ps1 は UTF-8 BOM付き・CRLF で保存:Windows PowerShell 5.1 は BOM 無し UTF-8 を システム既定コードページ(cp932)として誤読する。日本語を含む .ps1 だと文字列の引用符位置がずれて構文崩壊し、 スクリプトが実行されず文字列として出力されるだけになる(変数未代入で後段がエラー=「一度も起動していない」状態)。 .bat 経由でも同じ崩壊で無反応に見える。対応=UTF-8 BOM付き・CRLF で再保存、または非本質テキスト(コメント)を ASCII に 留める。実行ポリシー側の Restricted 拒否も併発しやすい(Set-ExecutionPolicy -Scope CurrentUser -ExecutionPolicy RemoteSigned)(aivony)。
  • VS Code devcontainer の自動ポートフォワーディングがホストのポートを握り bind 失敗:コンテナ内でサーバを テスト起動すると VS Code がホスト↔コンテナのポート転送を自動登録し、終了後もホスト側占有が残ることがある。 別ポートに変えても PORTS パネルに蓄積した転送一覧にその番号が含まれていると [Errno 10048] が再発。 対応=PORTS パネルで該当ポートの転送を手動停止(右クリック→「転送の停止」)(aivony)。

出典:gemini-rag(encoding)、mouse-release(SetForegroundWindow)、aivony(.ps1 BOM・ポート転送占有)