CRegKey::EnumKeyがうまく機能しない(ATL)

解決


duck_sheik  2006-09-01 15:54:19  No: 62883  IP: 192.*.*.*

ATLライブラリのCRegKeyクラスを使ってレジストリを操作してみました。しかし、メンバ関数の一つENumKeyがうまく動作せず、三回目の呼び出しで必ず失敗します。

参照:http://msdn2.microsoft.com/ja-jp/library/0y1bzwwk.aspx

//フォルダへの関連付け一覧を抽出
CRegKey reg;
DWORD keyIndex = 0,length;
char keyName[20][80];
reg.Open(HEKY_CLASSES_ROOT,"folder\\shell");
while(reg.ENumKey(keyIndex,keyName[keyIndex],&length) == ERROR_SUCCESS){
     // keyName[keyIndex]を出力するコードがここに入る
     keyIndex++;
}
//細かい間違いがあったらすみません

HKEY_CLASSES_ROOT\folder\shellにはサブキーが4つあるのですが、上のコードを実行するとkeyIndex==2となったところで関数がエラー値を返し(そこまでは正常に動作。エラー値はERROR_NO_MORE_ITEMSとは違う値)、ループが終了してしまいます。検索するキーの場所をHCR\folder\shell以外にしても、サブキーを2つまでしか検出できませんでした。またループや返り値判定を使わず手動で4回関数を呼び出しても、3回目の呼び出しでエラーになりました(バッファに文字列が格納されていない).

わかる方がおられましたらお願いします。

編集 削除
kure  2006-09-01 16:34:54  No: 62884  IP: 192.*.*.*

lengthが未初期化のために
keyNameに対して範囲外参照/書き込みをしていたりしませんか?

編集 削除
duck_sheik  2006-09-01 16:52:01  No: 62885  IP: 192.*.*.*

length = 0,  length = 79でそれぞれ初期化してみましたが、結果は同じでした。

ループ内にブレークポイントを設定してデバッグしたところ、最初のループではlength == 7(最初のサブキーは"explore"でした),二回目のループではlength == 4(二つ目のサブキー:"Open")ときちんとlengthの値は格納されています。しかし三回目の関数呼び出しにはやはり失敗しました。(length == 4のまま。keyName[3]も初期値と同じ。)

とりあえず返ってきたエラー値について情報を集めたいのですが、ATLライブラリ関数の返り値についてMSDNより詳しいところはあるのでしょうか・・・

編集 削除
duck_sheik  2006-09-01 17:01:54  No: 62886  IP: 192.*.*.*

追記です。

サブキーは4つあります。強引に関数EnumKeyの呼び出しを続けたところ、5回目の呼び出しではきちんとERROR_NO_MORE_ITEMSが返されていることがわかりました。3回目と4回目で失敗する理由は依然不明ですが、そこにキーがあることは認識していることはわかりました。

編集 削除
dairygoods  2006-09-01 17:23:59  No: 62887  IP: 192.*.*.*

呼び出す時 length にはバッファのサイズを指定するのでは?
(つまり、呼び出すごとに初期化)

編集 削除
duck_sheik  2006-09-01 18:11:43  No: 62888  IP: 192.*.*.*

できました。ありがとうございました。
lengthは読み込んだ文字数を格納するためだけのものだと思っていました(そのためkureさんのご指摘の意味がわからず、申し訳ありませんでした)。lengthがバッファサイズの指定と、読み込んだ文字数の格納の二つに使われていることに気づきませんでした。(自分でリンク貼っときながら・・・)初心者丸出しです。
今後はCStringの使えない(char*しか使えない)関数の扱いには特に気をつけるようにします。ありがとうございました。

編集 削除