C#操作注册表REG_DWORD类型键异常(RegistryValueKind.DWord异常)解决方案

         在用C#操作注册表时,如果注册表键的类型是REG_DWORD,有可能遇到溢出BUG。网上这方面的资料很少,在这共享一下。

         C#可以用RegistryKey类的SetValue方法来设置键值,例如:



         看起来一切正常,但是这个RegistryValueKind.DWord是有问题的。

         注册表中的REG_DWORD是无符号32位数值,而C#中的RegistryValueKind.DWord是有符号32位数值。这就意味着RegistryValueKind.DWord的表示范围比REG_DWORD小,因此导致直接传入一些大数时会抛出异常提示类型不正确。

         那么如何解决这个BUG呢?

         读者可能试图这样做:

         openKey.SetValue("NoViewOnDrive",Convert.ToInt32("ffffffff",16), RegistryValueKind.DWord);

         目的是强制把参数转换成32位有符号数,这样是不行的,同样提示异常,因为ffffffff已经超出了有符号32位数的表示范围,无法转换。

         或者这样做:

         openKey.SetValue("NoViewOnDrive",Convert.ToUInt32 ("ffffffff",16), RegistryValueKind.DWord);

         目的是把参数强制转换成无符号32位表示,这样同样不行,SetValue方法内部会自动把参数转换成有符号32位表示,因此,我们的转换是徒劳的,还会被转换回去,而转换回去后,又会提示超出范围。

         其实,解决这个问题的方法很简单,只要把转换过程放在unchecked语句里就行了,unchecked语句块内的转换,不做溢出检查,溢出了直接用补码表示。例如:


Int32 tempInt = 0; //预先定义一个有符号32位数

//unchecked语句块内的转换,不做溢出检查
unchecked
{
    tempInt = Convert.ToInt32("ffffffff", 16); //强制转换成有符号32位数
}

//此时的tempInt已经是有符号32位数,可以直接写入注册表
openKey.SetValue("NoViewOnDrive", tempInt, RegistryValueKind.DWord);

         这样转折一下,就可以成功写入注册表了。



posted @ 2012-11-28 16:28  杨元  阅读(1524)  评论(0编辑  收藏  举报