特殊な環境において
ocraでrubyスクリプトをexe化しようとすると
downcaseがどうこう言われてexe化に失敗する事があります。
原因は
ロード済みDLLの探索時にGetModuleFileNameが呼ばれるが、
マルチバイト文字列を適切にエンコードしないままになっているため
- アンチウィルス/パーソナルファイアウォールソフトが日本語ディレクトリ名に格納されてる
- ruby自体が日本語ディレクトリに格納されてる
などのケースに置いて失敗します。
後者はともかく、前者を対策するのは面倒くさい為ちゃっちゃとパッチ書いちゃう
patch.diff
diff U3Bb C:/Ruby21-x64/lib/ruby/gems/2.1.0/gems/ocra-1.3.5/bin/old-ocra C:/Ruby21-x64/lib/ruby/gems/2.1.0/gems/ocra-1.3.5/bin/ocra
--- C:/Ruby21-x64/lib/ruby/gems/2.1.0/gems/ocra-1.3.5/bin/old-ocra Fri May 22 18:24:56 2015
+++ C:/Ruby21-x64/lib/ruby/gems/2.1.0/gems/ocra-1.3.5/bin/ocra Fri May 22 18:38:21 2015
@@ -952,7 +952,7 @@
require 'Win32API'
enumprocessmodules = Win32API.new('psapi', 'EnumProcessModules', ['L','P','L','P'], 'L')
- getmodulefilename = Win32API.new('kernel32', 'GetModuleFileName', ['L','P','L'], 'L')
+ getmodulefilename = Win32API.new('kernel32', 'GetModuleFileNameW', ['L','P','L'], 'L')
getcurrentprocess = Win32API.new('kernel32', 'GetCurrentProcess', [], 'L')
bytes_needed = 4 * 32
@@ -968,9 +968,9 @@
handles = module_handle_buffer.unpack("I*")
handles.select { |handle| handle > 0 }.map do |handle|
- str = "\x00" * 256
- modulefilename_length = getmodulefilename.call(handle, str, str.size)
- Ocra.Pathname(str[0,modulefilename_length])
+ str = "\x00\x0" * 256
+ modulefilename_length = getmodulefilename.call(handle, str, str.size / 2)
+ Ocra.Pathname(str[0,modulefilename_length*2].force_encoding("utf-16le").encode "utf-8")
end
end
マルチバイト環境固有の問題は英語圏に説明するのは難しいし、いい感じのテストケース用意するのが難しすぎる