« msiを直接編集したい | トップページ | どこまで本気なのか »

2007年8月16日 (木)

.NET1.1でレジストリに空文字列を書くとVC++で読めない

気がついたら前回の記事から1ヶ月半経っている……

.NET 1.1(C#)だと、レジストリアクセスはだいたい以下のような感じになります。

RegistryKey hKey = Registry.CurrentUser.OpenSubKey("キーの名前", true);
hKey.SetValue("Test", "A");
string result = (string)hKey.GetValue("Test");

ちなみに、SetValueの2番目の引数と、GetValueの戻り値はともにObject型です。

通常であれば、上のコードを実行すると、resultには「A」が入ります。当たり前ですが。
また、値を空にしようとして空文字列をセットすると、resultにも空文字列が入ります。
「何を当たり前のことを」とお思いでしょうが、本題はここからです。

こうやって値をセットしたレジストリを、VC++で読んでみます。

HKEY rKey;
LONG bRet;
BYTE Data[256];
DWORD cbData;
DWORD dwType;
TCHAR buffer[1024];

bRet = RegOpenKeyEx(HKEY_CURRENT_USER, _T("キーの名前"), 0, KEY_READ, &rKey);
cbData = sizeof(Data);
bRet = RegQueryValueEx(rKey, _T("Test"), NULL, &dwType, Data, &cbData);
RegCloseKey(rKey);
_tcsncpy(buffer, (LPTSTR)Data, sizeof(Data));
_tprintf("Test: %s#\n", buffer);

さて、何が起きたでしょうか。たとえば、「A」が入っていれば

Test: A#

と表示されますが、空文字列が入っていると

Test:

とだけ表示されます。このとき、RegQueryValueEx関数から返ってきたときのcbDataの値は0になっており、
Dataの中身は何が入っているかよく判らない状態です。

これを回避するには、C#のほうで

hKey.SetValue("Test", "");

としてしまいたいところを

hKey.SetValue("Test", "\0");

と書くしかありません。確かに、こんなことが書かれています。

RegistryKey.SetValue メソッドのリファレンス(古いほう)
http://msdn.microsoft.com/library/ja/default.asp?url=/library/ja/cpref/html/frlrfmicrosoftwin32registrykeyclasssetvaluetopic.asp

「データは、null で終わる Unicode 文字列値として表されます。」

あえて言いたい、「だったらnullで終わってねぇ文字列受け付けんなよ!」と。

新しいほうのリファレンス(http://msdn2.microsoft.com/ja-jp/library/2kk9bxk9.aspx)にはそんなことちっとも書いてないですね。
2.0以降は直ってるってことでしょうか。誰か実験して教えてください。

|

« msiを直接編集したい | トップページ | どこまで本気なのか »

コメント

コメントを書く



(ウェブ上には掲載しません)




トラックバック

この記事のトラックバックURL:
http://app.cocolog-nifty.com/t/trackback/161557/16135385

この記事へのトラックバック一覧です: .NET1.1でレジストリに空文字列を書くとVC++で読めない:

« msiを直接編集したい | トップページ | どこまで本気なのか »