{windows]RubyスクリプトからWidowsAPIを呼び出す方法

ちょっと曖昧なところもあるけど、取り合えず呼び出すことができたのでメモっとく。

今回、WindowsAPIのSHChangeNotifyを呼び出す必要があって、その方法を調べた。

irbでためしたところ以下のような感じで呼び出すことに成功した。

irb(main):001:0> require 'Win32API'
=> true
irb(main):002:0> SHChangeNotify = Win32API.new("shell32.dll", "SHChangeNotify", "LILL", nil)
=> #<Win32API:0x7ff9f6e4>
irb(main):003:0> ASSOCCHANGED = 0x08000000
=> 134217728
irb(main):004:0> SHChangeNotify.call(ASSOCCHANGED, 0, 0, 0)
=> 0

上記を解説しておく

require 'Win32API'

WindowsAPIを呼び出すには、標準添付ライブラリの'Win32API'をrequireしておく必要がある。

SHChangeNotify = Win32API.new("shell32.dll", "SHChangeNotify", "LILL", nil)

Win32API.new()でAPI関数オブジェクトを生成している。引数は順番に、

"shell32.dll"
SHChangeNotify関数本体が含まれているDLL。API関数がどのDLLに含まれるかは、関数リファレンスの該当関数のページに記載されている..はず
"SHChangeNotify"
呼び出すAPI関数の名前。
"LILL"
関数の引数の型のリスト。詳細はWin32APIの関数リファレンス参照。SHChangeNotify関数の引数の型が、LONG, UINT, LPCVOID, LPCVOID となっているので適当に型を Long, Int, Long, Long と解釈した。このへんは適当なので間違ってる可能性大。
nil
戻り値の型。SHChangeNotify関数の戻り値はvoidで戻り値がない、ということでnilにしている。
ASSOCCHANGED = 0x08000000

"ファイルの関連付けの変更"をOSに通知するためには、SHChangeNotify関数の第一引数のEventIdでSHCNE_ASSOCCHANGEDを渡してあげると良いらしい。
このSHCNE_ASSOCCHANGEDというのは、ヘッダファイル"shlobj.h"の中で、0x08000000Lとして定義されている。
スクリプトを後から読んだときに、わかり易いように定数として定義しておく。

ちなみに、API関数がどのヘッダファイルで宣言されているかについても、Win32APIの関数リファレンスに載っている。

SHChangeNotify.call(ASSOCCHANGED, 0, 0, 0)

SHChangeNotify関数を実際に呼び出す。引数は順に

ASSOCCHANGED
"ファイル関連づけが変更になった"ことをOSに通知するためのイベントID
0
フラグ、APIリファレンスによると、SHCNF_IDLISTという値を渡すように指示されていた。このSHCNF_IDLISTという値は、ヘッダファイル"shlobj.h"の中で0に設定されていたので、0としている。
0
SHCNE_ASSOCCHANGEDの場合は未使用のためNULLとする、ということで0を渡している。
0
同上