DOBON.NET DOBON.NETプログラミング掲示板過去ログ

レジストリ(DWORD)にMAX値を設定したい

環境/言語:[WinXP または 2003Server/C#/.NET Framework 2.0]
分類:[.NET]

いつもお世話になっております。
どうしても解決できないことがあり、お力をお貸しください。

【やりたいこと】
NTPでどんなに時刻が違っていようとも強制的に時刻あわせをする(デフォルトは15時間以上違っていたら時刻あわせをしません。)ようにプログラムでレジストリを変更したい。
レジストリの
HKEY_LOCAL_MACHIN\SYSTEM\CurrentControlSet\Services\W32Time\Config
MaxNegPhaseCorrection(REG_DWORD)
MaxPosPhaseCorrection(REG_DWORD)
の値を変えようとしています。

【困っていること】
上記のことを実現するために、値を0xffffffffに変更したいのですが、どうしてもうまくいきません。

【実行結果】
(1)
string userRoot = Registry.LocalMachine.ToString();
string keyName = userRoot + "\\" + regPath;
Registry.SetValue(keyName, regKey, 0xffffffff);

4294967295 が設定されて、データ型が REG_SZになってしまう。

(2)
System.Int32 longValue=4294967295;
string userRoot = Registry.LocalMachine.ToString();
string keyName = userRoot + "\\" + regPath;
Registry.SetValue(keyName, regKey, longValue, RegistryValueKind.DWord);

エラーになる。
”値オブジェクトの型が指定された RegistryValueKind に一致しなかったか、またはオブジェクトを正しく変換できませんでした。”



おわかりになる方がいらっしゃったらお教えください。
よろしくお願いします。
自己RESです。

問題は解決したわけではないのですが、
>NTPでどんなに時刻が違っていようとも強制的に時刻あわせをする
という仕様を、1年以内の時刻差異だったら時刻あわせをする
というように、変えてもらいました。

一応解決とさせていただきます。
解決済み!
こんにちは。
私もちょっと試してみました。

> Registry.SetValue(keyName, regKey, 0xffffffff);

このコードだと確かにデータ型が REG_SZ になってしまいますね。
0xffffffff を 4294967295 という値(しかも文字列)だと認識されているようです。

で、そんなんじゃねえよ、0xffffffff は DWord なんだよってことで

> Registry.SetValue(keyName, regKey, 0xffffffff, RegistryValueKind.DWord);

と書いてみると、提示されているような

”値オブジェクトの型が指定された RegistryValueKind に一致しなかったか、またはオブジェクトを正しく変換できませんでした。”

という例外が起きてしまうわけで。
例外メッセージの行間を読めとはよく言われているわけですが
( NullReferenceException を除く)これもキチンと読むと解決方法が書い
てありそうな気がします。
値オブジェクトというと 0xffffffff のことですが、それの型が指定された
RegistryValueKind( RegistryValueKind.DWord のことですね)に一致しな
かったと。
でも設定したいのは DWord なんだから、間違っているのは 0xffffffff の
方?でも値自体は間違ってないよね、ってことになるわけですが。

ここで考えるのは、 0xffffffff は DWord ではどう表現すれば良いのか、と
いうこと。
JUN さんが書かれている 4294967295 は 0xffffffff を10進数で表した値
なわけですが、それって C# で言うとどんな型なん?と考えるに、Int32 の
範囲じゃないじゃん? Int32.MaxValue 超えとるやん?という話で。だった
ら uint でいいんじゃね?と

> Registry.SetValue(keyName, regKey, (uint)0xffffffff, RegistryValueKind.DWord);

こんなコードを書いても同じ例外が出てしまいます。まぁ当然ですが。
RegistryValueKind.DWord は Int32 を求めている、でも 0xffffffff は Int32
の範囲には収まらない。じゃあどーすんの?とオダギリジョーばりにカード
を並べてみると、以下のコードならいけそうだという話に(そこはお好みで
劇団ひとりでもいいですが)。

(1)
Registry.SetValue(keyName, regKey, unchecked ((Int32)0xffffffff), RegistryValueKind.DWord);

(2)
Registry.SetValue(keyName, regKey, -1, RegistryValueKind.DWord);

(1)案は、無理やり Int32 にキャストしちゃうとコンパイルエラーになってしま
うので、強引に unchecked キーワードをつけて道理を引っ込めてしまう
やり方。
(2)案は 0xffffffff って要するに全ビットが立った Int32、すなわち -1 じゃ
ね?ということで、最初から -1 をセットしてしまう方法。
どちらがお勧めかはまぁ時と場合によるわけですが、自分なら 0xffffffff
== -1 と頭の中で結びついているので(2)案を採用しそうですが、コードの
読みやすさと C# コンパイラの機嫌を損ねないような折衷案としては(1)か
なあ、と。

なんだか書いているうちに駄文になってしまっている気もしますが、わかり
ましたでしょうか。

# このあたりってビット演算とかを勉強しているとすぐ出てきそうだけど、最
# 近はそういうの研修とかでもやったりしないのかな。
# 自分が以前担当したときは親指で2進数を数えるところから教えましたが
# (古すぎ)
解決済み!
調べてみたらこんなのみつけますた ('A`)ゝ
http://dobon.net/vb/dotnet/beginner/literals.html
ぽぴ王子様、ガッ様

RESありがとうございます。

できました〜!! -1を設定する方法で実現しました。
ありがとうございます。

>>ぽぴ王子様
わざわざ試してくださったんですね。リスキーなテストなのにありがとうございます。
勉強になりました。
># このあたりってビット演算とかを勉強しているとすぐ出てきそうだけど、最
># 近はそういうの研修とかでもやったりしないのかな。
はるか昔、1と0が8つで1バイトってのは習ったことがあるような気がしますが、今まで実務で2進、16進とは無縁だったもので・・・。>言い訳です(笑)

>>ガッ様
教えていただいたサイト、勉強になりました。
VB6.0ユーザーだったので型変換に疎くてためになりました。ありがとうございます。
解決済み!
> わざわざ試してくださったんですね。リスキーなテストなのにありがとうございます。

まぁ試したことは試したんですが、キーはその辺の適当なところを選んで
やったので大丈夫ですよ。
ちょうど仕事でレジストリ操作の部分とか作ってたところなので、その辺を
少し改造して。

> はるか昔、1と0が8つで1バイトってのは習ったことがあるような気がしますが、今まで実務で2進、16進とは無縁だったもので・・・。>言い訳です(笑)

確かに、最近はそういったことを意識しなくてもプログラムは当たり前に組
める時代ですから、忘れちゃうのも仕方ないかもしれませんね。

基本的には

> 例外メッセージの行間を読めとはよく言われているわけですが
> ( NullReferenceException を除く)これもキチンと読むと解決方法が書い
> てありそうな気がします。

のあたりをキチンと守っていればなんとかなると思うので、今後ともがんばっ
てみてください。
NullRefernceException は
"オブジェクト参照がオブジェクト インスタンスに設定されていません。"
とか意味不明な文字列を返すので、行間を読んでもさっぱりだと思います :-)
解決済み!
ぽぴ王子様

>>はるか昔、1と0が8つで1バイトってのは習ったことがあるような気がしますが、今まで実務で2進、16進とは無縁だったもので・・・。>言い訳です(笑)
>
> 確かに、最近はそういったことを意識しなくてもプログラムは当たり前に組
> める時代ですから、忘れちゃうのも仕方ないかもしれませんね。
フォローありがとうございます(笑)。


> 基本的には
>
>>例外メッセージの行間を読めとはよく言われているわけですが
>>( NullReferenceException を除く)これもキチンと読むと解決方法が書い
>>てありそうな気がします。
>
> のあたりをキチンと守っていればなんとかなると思うので、今後ともがんばっ
> てみてください。

ハイ、がんばります。

昨日納品してきまいた。
本当にありがとうございました。
解決済み!

DOBON.NET | プログラミング道 | プログラミング掲示板