値が未設定のレジストリキーをRegQueryValueEx()で取得を試行時、abort()しないようにするには?

[戻る]
おもち 2017/12/13(水) 15:09:25
【用件】
レジストリキーには、値が設定されていない物( REG_SZ型で何も設定されておらず、名前が(既定)になっている値しか持っていないキー )が多々あります。
その値をRegQueryValueEx()で得ようとすると、取得失敗を返すのでなくabort()してしまいます。
一方、Win16からあるRegQueryValue()で同じ事をすると、abort()せず空データ取得と正常終了( ERROR_SUCCESSを関数値として返す )をします。

RegQueryValue()使用は避けたいのですが、上述のため 現状仕方なく使用中です。
が、何とか RegQueryValue() 同様の挙動を、RegQueryValueEx() か類似の単純な方法で実現する方法は無いでしょうか?

【具体例】
HKEY_CLASSES_ROOT\CLSID\{0C092C20-882C-11CF-A6BB-0080C7B2D682}キーに存在しない「 CoClassのフレンドリ名 」の取得試行時の挙動差。

// 1. HKEY_CLASSES_ROOT/CLSID をまず開き、その直下にあるCLSID群を次々に舐めたい。
RegOpenKeyExW( HKEY_CLASSES_ROOT, L"CLSID", 0, KEY_ALL_ACCESS, &Key );

// 2. ↓は1つのCLSIDだけ舐める実験。

// 2 - a. abort()が呼ばれず都合が良いが、Win16 APIを使ってしまっている。避けたい。
RegQueryValueW( Key, L"{0C092C20-882C-11CF-A6BB-0080C7B2D682}", CoClassFriendlyName, &CoClassFriendlyNameSize );

// 2 - b. abort()が呼ばてしまい都合が悪いが、Win32 APIのため使いたい。
//RegQueryValueExW( Key, L"{0C092C20-882C-11CF-A6BB-0080C7B2D682}", NULL, NULL, CoClassFriendlyName, &CoClassFriendlyNameSize );
                                                                                                                        【環境】
・VS2017 VC++ コンソールアプリケーション、x64プラットフォーム
・Windows SDK 10.0.16299.0
・Win7 Ent. x64 + 最新のWindows Update

仲澤@失業者 2017/12/13(水) 16:09:45
abort()が何を意味するのか不明(例外でしょうか、落ちるのでしょうか)ですが、
次の点は試してみてはどうでしょう。

○第4引数「DWORD * : データ型が格納されるバッファ」にNULLでなく正常なポインタを
与えてみる。

それでもだめな場合は「値の無いエントリにRegQueryValueEx()は使えない」という
結論が得られますので、対象エントリの「親エントリ」を開いて、

 RegEnumValue()

を使って、「子エントリ」の情報を取得し、目的を果たす
という方法になるかと思います。

おもち 2017/12/14(木) 10:19:40
[[解決]]
自己解決致しました。下記のように、RegOpenKeyExW()で対処できました。

abort()は RegOpenKeyExW() 内で呼ばれていなかった( 常識的に、レジストリキーが見つか
らないというよくある失敗時に、abort()してしまうシステムコール仕様になっている筈が
ない )。

RegOpenKeyExW()の関数値の成否検査( ERROR_SUCCESSが返るか否か )を行う 自身が書いた
assert()に失敗し、それが呼んでいる物だった。

このassert()は RegOpenKeyExW() と同一行に書いた( MFCのVERIFY同様に使った )ため、
RegOpenKeyExW() 内でabort()したと誤解しまっていた。

RegOpenKeyExW() は目的のレジストリキーが見つからなかった時、ERROR_SUCCESS以外のエ
ラー値を返す。RegOpenKeyW() と異なる挙動になってしまっているが、自然な挙動に改版さ
れたように思える。
かつ得られなかった事を検出できるため、呼び出す側に対処する機会が与えられる。

お騒がせ致しました。

古いスレッドには追加発言できません。