JavaでWindowsレジストリを操作する
JavaからWindowsのレジストリの読み書きを行う。これはかなり単純な話なのだが、なかなか資料が見つからないのでどうやるのかわからないかもしれない。JNIを使うことがわかっても、これには様々なライブラリがあるため、どれを使うか迷うところだろう。
ここではJNAを使うことにする。
JNA-platformを依存に含める
以下はgradleを使用した場合の最新のJNA-platformを指定した例だ。
dependencies {
compile group: 'net.java.dev.jna', name: 'jna-platform', version: '4.5.2'
}
jnaとjna-platformがあるのだが、jna-platformの場合には、サポートする各プラットフォーム固有の(この場合はWindows固有の)のAPIが定義されている。当然他のプラットフォーム(Mac, Unix)のものも定義されているので、余計と言えば余計なのだが仕方がない。当然jna-platformを指定するとjnaも、もれなくついてくる。
レジストリの構造
レジストリを下手にいじるとマシンが起動さえしなくなるぞと脅されるのはいつものことである。以下は覚悟のある人向けのものだが、それほど無茶なことはしていない。
ここでレジストリの構造を解説しようとも思ったのだが、これは探せばいくらでもあると思うので省略する。
注意しなければならないことは。各レジストリキーには、デフォルト(規定)というものと任意の名前付のものがあり、それぞれ文字列値、バイナリ値、DWORD値などの型を持つことだ。
以下では、文字列に限ってやってみる。
対象とするルートとキー
ルートとしてはHKEY_CLASSES_ROOTとし、その中の.(ドット)で始まるエントリはファイル拡張子に対する処理を表すため、ここにありそうも無いファイル拡張子のためのエントリを作成してみる。
ただし、正式なエントリでは無いので、ファイル拡張子用の形式ではない。また、実験の後は当然のことながら削除してしまってよい。
キーを作成する
キーを作成するには次のようにする。
import static com.sun.jna.platform.win32.WinReg.*;
import com.sun.jna.platform.win32.*;
....
Advapi32Util.registryCreateKey(HKEY_CLASSES_ROOT, ".00001\\00002");
既に.00001\00002が存在している場合でもこれを行って良い。エラーは発生しない。また、.00001がなければ、これも同時に作成されるようだ。これを行っただけで、以下が作成される。
※RegEditの表示メニューから「最新の状態に更新」を行うこと。
値を設定してみる
値を設定する。設定する値の種類によってメソッドが異なるのだが、ここでは文字列のみを設定してみる。
Advapi32Util.registrySetStringValue(HKEY_CLASSES_ROOT, ".00001\\00002", "", "123");
Advapi32Util.registrySetStringValue(HKEY_CLASSES_ROOT, ".00001\\00002", "a", "abc");
つまり、先のメソッド呼び出しで、nameの部分を空文字列にすると、(規定)が設定されるようだ。
値を読み出してみる
System.out.println(Advapi32Util.registryGetStringValue(HKEY_CLASSES_ROOT, ".00001\\00002", "a"));
try {
System.out.println(Advapi32Util.registryGetStringValue(HKEY_CLASSES_ROOT, ".00001\\00002", "b"));
} catch (Win32Exception ex) {}
try {
System.out.println(Advapi32Util.registryGetStringValue(HKEY_CLASSES_ROOT, ".00001\\11111", "a"));
} catch (Win32Exception ex) {}
先に書いた値”a”と、存在しない値を読み出してみる。値が存在しない場合にはWin32Exceptionが発生するのだが、なぜかそのメッセージは常に「ファイルが見つかりません」になっている。
abc
指定されたファイルが見つかりません。
指定されたファイルが見つかりません。
まとめ
レジストリの読み書きとしては、かように単純な仕組みになっている。むしろ、レジストリの状態を破壊しないように、細心の注意を払うことの方が重要だろう。