【用件】
レジストリキーには、値が設定されていない物( 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, LCLSID, 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
abort()が何を意味するのか不明(例外でしょうか、落ちるのでしょうか)ですが、
次の点は試してみてはどうでしょう。
○第4引数「DWORD * : データ型が格納されるバッファ」にNULLでなく正常なポインタを
与えてみる。
それでもだめな場合は「値の無いエントリにRegQueryValueEx()は使えない」という
結論が得られますので、対象エントリの「親エントリ」を開いて、
RegEnumValue()
を使って、「子エントリ」の情報を取得し、目的を果たす
という方法になるかと思います。
自己解決致しました。下記のように、RegOpenKeyExW()で対処できました。
abort()は RegOpenKeyExW() 内で呼ばれていなかった( 常識的に、レジストリキーが見つか
らないというよくある失敗時に、abort()してしまうシステムコール仕様になっている筈が
ない )。
RegOpenKeyExW()の関数値の成否検査( ERROR_SUCCESSが返るか否か )を行う 自身が書いた
assert()に失敗し、それが呼んでいる物だった。
このassert()は RegOpenKeyExW() と同一行に書いた( MFCのVERIFY同様に使った )ため、
RegOpenKeyExW() 内でabort()したと誤解しまっていた。
RegOpenKeyExW() は目的のレジストリキーが見つからなかった時、ERROR_SUCCESS以外のエ
ラー値を返す。RegOpenKeyW() と異なる挙動になってしまっているが、自然な挙動に改版さ
れたように思える。
かつ得られなかった事を検出できるため、呼び出す側に対処する機会が与えられる。
お騒がせ致しました。