zoukankan      html  css  js  c++  java
  • 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);

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



  • 相关阅读:
    优化算法-BFGS
    Go语言及Web框架Beego环境无脑搭建
    使用WCF扩展记录服务调用时间
    红黑树LLRB
    springmvc国际化 基于请求的国际化配置
    Adapter Pattern
    泡泡屏保
    使用WCF扩展在方法调用前初始化环境
    OAuth的一个.NET开源实现
    Google C++编程风格指南
  • 原文地址:https://www.cnblogs.com/iyangyuan/p/2801800.html
Copyright © 2011-2022 走看看