AutoHotKey

AutoHotKeyでファイル読み込み時に日本語が文字化けする対策

https://yuis.xsrv.jp/images/ss/ShareX_ScreenShot_790f3d82-05f3-4528-be52-177fc4d21a6c.png

AutoHotKeyでの文字化け対策記事はいくつか書いているんですが、今回は少し難易度が高いですね。僕はプログラマの勘というやつですぐ解決できましたが、autohotkeyだけしか知らないという方は解決は厳しいかもしれません。とはいえ、安心してください。この記事で解決できますよ。

僕はbashコマンドを実行して標準出力を返す関数をautohotkeyで以下のように実装しておりました。

 getexec(command){

   ; Run, bash.exe -c '%command% > /mnt/c/pg/autohotkey/getexec.tmp.txt', ,hide
   RunWait, bash.exe -c '%command% > /mnt/c/pg/autohotkey/getexec.tmp.txt', ,hide

   ; sleep 200
   sleep 50

   FileRead, OutputVar, C:/pg/autohotkey/getexec.tmp.txt

   return OutputVar

 }

いつもは以下のように日本語が混じってくることはなかったのですが。

:*:isodate ::
  sendText( RegExReplace( getexec("date +%FT%T%Z") , "\s*(\n|\r\n)$", A_Space) )
return

日本語が含まれた出力が必要になりそうだったので、とりあえずテストしてみると、

:*:hoge ::
  sendText( RegExReplace( getexec("bash -c date") , "\s*(\n|\r\n)$", A_Space) )  
return

https://yuis.xsrv.jp/images/ss/ShareX_ScreenShot_2bcb21a3-ac5d-4d32-a09e-04f68f266e08.gif

見事に文字化けってしまいました。

で早速解決策ですが。

2通りあります。

  • FileEncoding , UTF-8を置く
  • FileReadの代わりにFileOpenを使う

どちらの方法にせよ、まずはautohotkeyファイルの文字コードとBOMがしっかり出来ているか確認しましょう。これはautohotkeyerの間では常識です。

https://yuis.xsrv.jp/images/ss/ShareX_ScreenShot_c7835c30-dad8-4865-8341-352a671e9a75.png

以下コマンドで一瞬で解決。

nkf --overwrite --oc=UTF-8-BOM dev.ahk

ではまずひとつめ。

AutoHotKeyではデフォルトのファイルエンコーディングの設定というのができるようで、この変数を定義します。

FileEncoding – Syntax & Usage | AutoHotkey

ので、以下のようになる。

 getexec(command){

   ; Run, bash.exe -c '%command% > /mnt/c/pg/autohotkey/getexec.tmp.txt', ,hide
   RunWait, bash.exe -c '%command% > /mnt/c/pg/autohotkey/getexec.tmp.txt', ,hide

   ; sleep 200
   sleep 50

   FileEncoding , UTF-8
   FileRead, OutputVar, C:/pg/autohotkey/getexec.tmp.txt

   return OutputVar

 }

~~これでおkですが、注意。これは関数内で定義しないと意味ないので、グローバルで定義しないようにしましょう。~~ グローバルで定義していけました。しかし関数定義よりも前に定義しておく必要があるので注意。先頭行あたりに置いておきましょう。

して、ふたつめ。

FileOpenを使用する方法です。

Force a file to be read as UTF-8? – AutoHotkey Community
FileOpen() – Syntax & Usage | AutoHotkey

以下のようになります。

getexec(command){

  RunWait, bash.exe -c '%command% > /mnt/c/pg/autohotkey/getexec.tmp.txt', ,hide

  ; sleep 200
  sleep 50

  ; FileRead, OutputVar, C:/pg/autohotkey/getexec.tmp.txt
  file := FileOpen("C:/pg/autohotkey/getexec.tmp.txt", "r", "UTF-8")
  content := file.Read()

  return content

}

どっちの方法でもいけますが、あとからショートカットが判明したFileEncodingのほうが使い勝手は良さそうです。